[GH-ISSUE #1430] How to return custom Response object from auth middlewares? #8749

Closed
opened 2026-04-13 03:56:55 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @MadadiSaeed on GitHub (Feb 13, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/1430

I have a translation layer for handling auth errors and I want to return my custom formatted errors. So how to return custom Response object from auth middlewares?

Originally created by @MadadiSaeed on GitHub (Feb 13, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/1430 I have a translation layer for handling auth errors and I want to return my custom formatted errors. So how to return custom Response object from auth middlewares?
GiteaMirror added the locked label 2026-04-13 03:56:55 -05:00
Author
Owner

@jslno commented on GitHub (Feb 13, 2025):

https://www.better-auth.com/docs/concepts/hooks#json-responses

<!-- gh-comment-id:2657322870 --> @jslno commented on GitHub (Feb 13, 2025): https://www.better-auth.com/docs/concepts/hooks#json-responses
Author
Owner

@MadadiSaeed commented on GitHub (Feb 13, 2025):

What I want to do is to catch auth errors from after middleware hooks and handle the error by creating my custom error and returning that error or object. But it seems it does not work with json function. And I just receive better auth own errors in the client.

Edit: In the docs it is said that after hooks is for to modify responses. But I could not find a way to modify or return my own custom error response.

<!-- gh-comment-id:2657496455 --> @MadadiSaeed commented on GitHub (Feb 13, 2025): What I want to do is to catch auth errors from after middleware hooks and handle the error by creating my custom error and returning that error or object. But it seems it does not work with `json` function. And I just receive better auth own errors in the client. Edit: In the docs it is said that `after hooks` is for to modify responses. But I could not find a way to modify or return my own custom error response.
Author
Owner

@arorajatin commented on GitHub (Mar 4, 2025):

Facing the same issue. There seems to be no way of modifying a particular type of response with addition information.

<!-- gh-comment-id:2697325084 --> @arorajatin commented on GitHub (Mar 4, 2025): Facing the same issue. There seems to be no way of modifying a particular type of response with addition information.
Author
Owner

@xorweak commented on GitHub (Mar 14, 2025):

I'm using app.onError with instanceOf ... has a workaround for your use-case.

However, I am trying to m modify the response to 'populate' the permissions array into the 'user' object. Docs states that can be done by modifying the response object in onResponse, but response object does not provide a way to modify the response body itself. Does anyone know how to do this?

EDIT:

I've browsing the source and found the correct way of returning the modified response:

const populatePermissionsPlugin = ()=>{

  return {
    id:         'populate-permissions-plugin',
    onResponse: async(response) => {

      const oldResponse = await response.json();
      return {
        response: { ...oldResponse, newResponse: true }
      }
    }
  } satisfies BetterAuthPlugin
}

source code

However, doing so doesn't work either. This seems like a bug...?

EDIT2: SOLUTION

I've discovered what the problem is. Seems like 'better-call' library expects response to be a Response object rather than a raw modified response body. Which seems correct.

See: better-call builded source line 4844

4841  return {
4842    handler: async (request) => {
4843      const onReq = await config?.onRequest?.(request);
4844      if (onReq instanceof Response) {
4845        return onReq;
4846      }
4847      const req = onReq instanceof Request ? onReq : request;
4848      const res = await processRequest(req);
4849      const onRes = await config?.onResponse?.(res);
4850      if (onRes instanceof Response) {
4851        return onRes;
4852      }
4853      return res;
4854    },

So, for achieving what I need, I did this:

const populatePermissionsPlugin = ()=>{

  return {
    id:         'populate-permissions-plugin',
    onResponse: async(response) => {
      const rawResponseBody = await response.json()

      // Inject something into the user object
      rawResponseBody.user.injected = true

      return {
        response: new Response(JSON.stringify(
           rawResponseBody
      ), response)
      }
    }
  } satisfies BetterAuthPlugin
}

Maybe adding a more clear example in the docs could help to know this, because what I tried first is modify the 'response' object coming in the function, but it is not writable (because it has no setters), so it is a bit confusing.

<!-- gh-comment-id:2725589910 --> @xorweak commented on GitHub (Mar 14, 2025): I'm using `app.onError` with `instanceOf ...` has a workaround for your use-case. However, I am trying to m modify the response to 'populate' the permissions array into the 'user' object. Docs states that can be done by modifying the response object in [onResponse](https://www.better-auth.com/docs/concepts/plugins#on-response), but response object does not provide a way to modify the response body itself. Does anyone know how to do this? **EDIT:** I've browsing the source and found the correct way of returning the modified response: ```javascript const populatePermissionsPlugin = ()=>{ return { id: 'populate-permissions-plugin', onResponse: async(response) => { const oldResponse = await response.json(); return { response: { ...oldResponse, newResponse: true } } } } satisfies BetterAuthPlugin } ``` [source code](https://github.com/better-auth/better-auth/blob/e157e06a5159d53c2fb6e319da9d9ae995dcb7b2/packages/better-auth/src/api/index.ts#L158) However, doing so doesn't work either. This seems like a bug...? **EDIT2: SOLUTION** I've discovered what the problem is. Seems like 'better-call' library expects response to be a `Response` object rather than a raw modified response body. Which seems correct. See: [better-call builded source](https://www.npmjs.com/package/better-call?activeTab=code) line 4844 ``` 4841 return { 4842 handler: async (request) => { 4843 const onReq = await config?.onRequest?.(request); 4844 if (onReq instanceof Response) { 4845 return onReq; 4846 } 4847 const req = onReq instanceof Request ? onReq : request; 4848 const res = await processRequest(req); 4849 const onRes = await config?.onResponse?.(res); 4850 if (onRes instanceof Response) { 4851 return onRes; 4852 } 4853 return res; 4854 }, ``` So, for achieving what I need, I did this: ```javascript const populatePermissionsPlugin = ()=>{ return { id: 'populate-permissions-plugin', onResponse: async(response) => { const rawResponseBody = await response.json() // Inject something into the user object rawResponseBody.user.injected = true return { response: new Response(JSON.stringify( rawResponseBody ), response) } } } satisfies BetterAuthPlugin } ``` Maybe adding a more clear example in the docs could help to know this, because what I tried first is modify the 'response' object coming in the function, but it is not writable (because it has no setters), so it is a bit confusing.
Author
Owner

@yashwanth2804 commented on GitHub (Apr 17, 2025):

I too ran in this issue , ability to modify the response is great feature,

i want to create user org automatically after signup using hooks after, and return the created one back to user simply

 return ctx.json({
                org-id: "someslug",
                });

this is making the api error skip in the web.

may be without any plugins i want to change on the fly in hooks easily

<!-- gh-comment-id:2812939160 --> @yashwanth2804 commented on GitHub (Apr 17, 2025): I too ran in this issue , ability to modify the response is great feature, i want to create user org automatically after signup using hooks `after`, and return the created one back to user simply ``` return ctx.json({ org-id: "someslug", }); ``` this is making the api error skip in the web. may be without any plugins i want to change on the fly in hooks easily
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#8749