elysia icon indicating copy to clipboard operation
elysia copied to clipboard

onResponse handler neither has the response object nor the Request socket object available (TS)

Open otherguy opened this issue 1 year ago • 2 comments
trafficstars

Creating a new issue since #190 was closed.

Unfortunately, the onResponse handler can neither access the actual Response object (to get e.g. response length) nor does it have access to the underlying socket, to get the request protocol for example.

Would it be possible to get the Response object inside the context of the onResponse handler? And an access to req.socket in the TypeScript Request object?

Responding to

In 0.7.0, you should be able to access Response in afterHandle as the following.

new Elysia()
  .onAfterHandle(({ response }) => {
})

Originally posted by @SaltyAom in https://github.com/elysiajs/elysia/issues/190#issuecomment-1813985800

Using [email protected], in a minimal example, when used as a middleware, response is undefined.

What I would want is to get the response object (to get the response size) in either onAfterHandle or, preferably, onResponse.

Similarly, in onResponse, it would be great to have access to ctx.request.socket to get the original request protocol.

return app
  .derive((ctx) => {
    return {
      ip: String(getIP(ctx.request.headers))
    };
  })
  .onError((ctx) => {
    ctx.store = { error: ctx.error, ...ctx.store };
  })
  .onRequest((ctx) => {
    ctx.store = { requestStart: process.hrtime.bigint(), ...ctx.store };
  })
  .onAfterHandle(({response}) => {
    console.log(response);
  })
  .onResponse((ctx) => {
  })

otherguy avatar Nov 20 '23 14:11 otherguy

@SaltyAom any progress on this one?

otherguy avatar Aug 22 '24 12:08 otherguy

If I understand correctly, you want to get both request, and response on onAfterResponse (previously 'onResponse').

onAfterResponse include response by default since name change or since 1.1.

new Elysia()
	.derive(({ server, request }) => {
		return {
			ip: String(server?.requestIP(request))
		}
	})
	.onError((ctx) => {
		ctx.store = { error: ctx.error, ...ctx.store }
	})
	.onRequest((ctx) => {
		ctx.store = { requestStart: process.hrtime.bigint(), ...ctx.store }
	})
	.onAfterResponse(({ request, response }) => {
		console.log({
			request,
			response
		})
	})
	.get('/', () => 'a')
	.listen(3000)

SaltyAom avatar Aug 30 '24 17:08 SaltyAom

Is there any update here?

After some trying and debugging the onAfterResponse I found it very confusing that:

  • response is the response body (so whatever you return from the endpoints) instead of the Response object
  • body it seems to be always empty
  • headers is request headers instead of response headers. To get response headers you must check set.headers
  • You can use error, but technically this is after response, so what's the point? I would expect to be an Error in case there is one
  • the status comes from set.status as well instead than from the confusing response body.

After know this, I think is manageable, I could do everything I wanted to. However, under my point of view this is very confusing for new people using ElysiaJS. Again, maybe is just a matter of updating docs??

AlbertSabate avatar Nov 08 '24 12:11 AlbertSabate