diff --git a/src/compose.ts b/src/compose.ts index 0e5fa6c6..48949a10 100644 --- a/src/compose.ts +++ b/src/compose.ts @@ -2344,9 +2344,10 @@ export const composeErrorHandler = ( } fnLiteral += `if(error.constructor.name === "ValidationError" || error.constructor.name === "TransformDecodeError") { - set.status = error.status ?? 422 + const reportedError = error.error ?? error + set.status = reportedError.status ?? 422 return new Response( - error.message, + reportedError.message, { headers: Object.assign( { 'content-type': 'application/json'}, diff --git a/src/dynamic-handle.ts b/src/dynamic-handle.ts index 7ab208dc..992dff5b 100644 --- a/src/dynamic-handle.ts +++ b/src/dynamic-handle.ts @@ -17,6 +17,7 @@ import { redirect, signCookie, StatusMap } from './utils' import { parseCookie } from './cookies' import type { Handler, LifeCycleStore, SchemaValidator } from './types' +import { TransformDecodeError } from '@sinclair/typebox/value' // JIT Handler export type DynamicHandler = { @@ -420,11 +421,13 @@ export const createDynamicHandler = return (context.response = mapResponse(response, context.set)) } catch (error) { - if ((error as ElysiaErrors).status) - set.status = (error as ElysiaErrors).status - + const reportedError = (error instanceof TransformDecodeError && error.error) + ? error.error + : error + if ((reportedError as ElysiaErrors).status) + set.status = (reportedError as ElysiaErrors).status // @ts-expect-error private - return app.handleError(context, error) + return app.handleError(context, reportedError) } finally { for (const afterResponse of app.event.afterResponse) await afterResponse.fn(context as any) diff --git a/test/core/handle-error.test.ts b/test/core/handle-error.test.ts index d988c680..73d5a8e8 100644 --- a/test/core/handle-error.test.ts +++ b/test/core/handle-error.test.ts @@ -204,4 +204,25 @@ describe('Handle Error', () => { 'APIError' ) }) + + it('handle error in Transform', async () => { + const route = new Elysia().get('/', ({query: {aid}}) => aid, { + query: t.Object({ + aid: t.Transform(t.String()) + .Decode((value) => { + throw new NotFoundError('foo') + }) + .Encode((value) => `1`) + }) + }) + + let response = await (new Elysia({ aot: false })).use(route).handle(req('/?aid=a')) + expect(response.status).toEqual(404) + expect(await response.text()).toEqual('foo') + + response = await (new Elysia({aot: true})).use(route).handle(req('/?aid=a')) + expect(response.status).toEqual(404) + expect(await response.text()).toEqual('foo') + }) + })