diff --git a/packages/better-call/src/error.ts b/packages/better-call/src/error.ts index 8a6b134..259b02e 100644 --- a/packages/better-call/src/error.ts +++ b/packages/better-call/src/error.ts @@ -249,9 +249,18 @@ export class BetterCallError extends Error { } } -export const kAPIErrorHeaderSymbol = Symbol.for( - "better-call:api-error-headers", -); +const errorMetaMap = new WeakMap(); + +/** + * @internal + */ +export function __setErrorMeta(error: Error, headers: Headers): void { + errorMetaMap.set(error, headers); +} + +export function getErrorMeta(error: Error): Headers | undefined { + return errorMetaMap.get(error); +} export type APIError = InstanceType; export const APIError = makeErrorForHideStackFrame(InternalAPIError, Error); diff --git a/packages/better-call/src/index.ts b/packages/better-call/src/index.ts index 28b6cea..1f64904 100644 --- a/packages/better-call/src/index.ts +++ b/packages/better-call/src/index.ts @@ -1,5 +1,3 @@ -// Core - // Cookies export type { CookieOptions, CookiePrefixOptions } from "./cookies"; export { serializeSignedCookie } from "./cookies"; @@ -15,7 +13,7 @@ export type { Status } from "./error"; export { APIError, BetterCallError, - kAPIErrorHeaderSymbol, + getErrorMeta, statusCodes, ValidationError, } from "./error"; diff --git a/packages/better-call/src/middleware.test.ts b/packages/better-call/src/middleware.test.ts index 9a47824..4e31151 100644 --- a/packages/better-call/src/middleware.test.ts +++ b/packages/better-call/src/middleware.test.ts @@ -1,6 +1,6 @@ import { describe, expect, expectTypeOf, it } from "vitest"; import { createEndpoint } from "./endpoint"; -import { APIError, kAPIErrorHeaderSymbol } from "./error"; +import { APIError, getErrorMeta } from "./error"; import { createMiddleware } from "./middleware"; describe("type", () => { @@ -170,8 +170,8 @@ describe("creator", () => { await expect(middleware({})).rejects.toThrowError(APIError); await expect( middleware({}).catch((e: any) => { - const headers = e[kAPIErrorHeaderSymbol] as Headers; - expect(headers.get("X-Test")).toBe("test"); + const headers = getErrorMeta(e); + expect(headers?.get("X-Test")).toBe("test"); }), ).resolves.toBeUndefined(); }); diff --git a/packages/better-call/src/middleware.ts b/packages/better-call/src/middleware.ts index e9fdbf6..80b41f7 100644 --- a/packages/better-call/src/middleware.ts +++ b/packages/better-call/src/middleware.ts @@ -1,7 +1,7 @@ import { createInternalContext } from "./context"; import type { CookieOptions, CookiePrefixOptions } from "./cookies"; import type { Status, statusCodes } from "./error"; -import { type APIError, kAPIErrorHeaderSymbol } from "./error"; +import { type APIError, __setErrorMeta } from "./error"; import type { Prettify } from "./helper"; import type { InferUse } from "./types"; import { isAPIError } from "./utils"; @@ -198,15 +198,8 @@ export function createMiddleware(handler: any) { } : response; } catch (e) { - // fixme(alex): this is workaround that set-cookie headers are not accessible when error is thrown from middleware if (isAPIError(e)) { - Object.defineProperty(e, kAPIErrorHeaderSymbol, { - enumerable: false, - configurable: false, - get() { - return internalContext.responseHeaders; - }, - }); + __setErrorMeta(e, internalContext.responseHeaders); } throw e; } @@ -246,13 +239,7 @@ createMiddleware.create = < return context.returnHeaders ? { headers, response } : response; } catch (e) { if (isAPIError(e)) { - Object.defineProperty(e, kAPIErrorHeaderSymbol, { - enumerable: false, - configurable: false, - get() { - return internalContext.responseHeaders; - }, - }); + __setErrorMeta(e, internalContext.responseHeaders); } throw e; } @@ -277,13 +264,7 @@ createMiddleware.create = < return context.returnHeaders ? { headers, response } : response; } catch (e) { if (isAPIError(e)) { - Object.defineProperty(e, kAPIErrorHeaderSymbol, { - enumerable: false, - configurable: false, - get() { - return internalContext.responseHeaders; - }, - }); + __setErrorMeta(e, internalContext.responseHeaders); } throw e; }