diff --git a/src/dynamic-handle.ts b/src/dynamic-handle.ts index c4dcd519..dea68ed1 100644 --- a/src/dynamic-handle.ts +++ b/src/dynamic-handle.ts @@ -5,6 +5,7 @@ import { ElysiaCustomStatusResponse, type ElysiaErrors, NotFoundError, + ParseError, status, ValidationError } from './error' @@ -264,25 +265,31 @@ export const createDynamicHandler = (app: AnyElysia) => { return await hooks.config.mount(request) let body: string | Record | undefined + try { if (request.method !== 'GET' && request.method !== 'HEAD') { if (content) { switch (content) { + case 'json': case 'application/json': body = (await request.json()) as any break + case 'text': case 'text/plain': body = await request.text() break + case 'urlencoded': case 'application/x-www-form-urlencoded': body = parseQuery(await request.text()) break + case 'arrayBuffer': case 'application/octet-stream': body = await request.arrayBuffer() break + case 'formdata': case 'multipart/form-data': { body = {} @@ -310,90 +317,92 @@ export const createDynamicHandler = (app: AnyElysia) => { const index = contentType.indexOf(';') if (index !== -1) contentType = contentType.slice(0, index) + } - // @ts-expect-error - context.contentType = contentType - - if (hooks.parse) - for (let i = 0; i < hooks.parse.length; i++) { - const hook = hooks.parse[i].fn - - if (typeof hook === 'string') - switch (hook) { - case 'json': - case 'application/json': - body = (await request.json()) as any - break - - case 'text': - case 'text/plain': - body = await request.text() - break - - case 'urlencoded': - case 'application/x-www-form-urlencoded': - body = parseQuery( - await request.text() - ) - break + // @ts-expect-error + context.contentType = contentType ?? '' - case 'arrayBuffer': - case 'application/octet-stream': - body = await request.arrayBuffer() - break + if (hooks.parse) + for (let i = 0; i < hooks.parse.length; i++) { + const hook = hooks.parse[i].fn - case 'formdata': - case 'multipart/form-data': { - body = {} + if (typeof hook === 'string') + switch (hook) { + case 'json': + case 'application/json': + body = (await request.json()) as any + break - const form = await request.formData() - for (const key of form.keys()) { - if (body[key]) continue + case 'text': + case 'text/plain': + body = await request.text() + break - const value = form.getAll(key) - const finalValue = normalizeFormValue(value) + case 'urlencoded': + case 'application/x-www-form-urlencoded': + body = parseQuery( + await request.text() + ) + break - if (key.includes('.') || key.includes('[')) - setNestedValue(body, key, finalValue) - else body[key] = finalValue - } + case 'arrayBuffer': + case 'application/octet-stream': + body = await request.arrayBuffer() + break - break - } + case 'formdata': + case 'multipart/form-data': { + body = {} - default: { - const parser = app['~parser'][hook] - if (parser) { - let temp = parser( - context as any, - contentType - ) - if (temp instanceof Promise) - temp = await temp - - if (temp) { - body = temp - break - } - } - break + const form = await request.formData() + for (const key of form.keys()) { + if (body[key]) continue + + const value = form.getAll(key) + const finalValue = normalizeFormValue(value) + + if (key.includes('.') || key.includes('[')) + setNestedValue(body, key, finalValue) + else body[key] = finalValue } + + break } - else { - let temp = hook(context as any, contentType) - if (temp instanceof Promise) - temp = await temp - if (temp) { - body = temp + default: { + const parser = app['~parser'][hook] + if (parser) { + let temp = parser( + context as any, + contentType + ) + if (temp instanceof Promise) + temp = await temp + + if (temp) { + body = temp + break + } + } break } } + else { + let temp = hook(context as any, contentType) + if (temp instanceof Promise) + temp = await temp + + if (temp) { + body = temp + break + } } + } - // @ts-expect-error - delete context.contentType + // @ts-expect-error + delete context.contentType + if (contentType) { // body might be empty string thus can't use !body if (body === undefined) { switch (contentType) { @@ -435,6 +444,9 @@ export const createDynamicHandler = (app: AnyElysia) => { } } } + } catch (error) { + throw new ParseError(error instanceof Error ? error : undefined) + } context.route = route context.body = body @@ -880,6 +892,11 @@ export const createDynamicErrorHandler = (app: AnyElysia) => { }, error: ElysiaErrors ) => { + if (error instanceof ElysiaCustomStatusResponse) { + context.set.status = error.code + return mapResponse(error.response, context.set) + } + const errorContext = Object.assign(context, { error, code: error.code }) errorContext.set = context.set