From 83f87761b0ebbaef276e7706b6d91b55d7210b28 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 26 Jun 2024 18:17:38 -0600 Subject: [PATCH 1/4] Allow parsing statusCode from error.cause --- src/error.ts | 7 +++++++ test/error.test.ts | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/error.ts b/src/error.ts index 956e3f9d..b07373f7 100644 --- a/src/error.ts +++ b/src/error.ts @@ -121,6 +121,13 @@ export function createError( err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode); } else if (input.status) { err.statusCode = sanitizeStatusCode(input.status, err.statusCode); + } else if ( + typeof input.cause === "object" && + input.cause && + "statusCode" in input.cause && + typeof input.cause.statusCode === "number" + ) { + err.statusCode = sanitizeStatusCode(input.cause.statusCode, err.statusCode); } if (input.statusMessage) { err.statusMessage = input.statusMessage; diff --git a/test/error.test.ts b/test/error.test.ts index 6ce186f5..04117b08 100644 --- a/test/error.test.ts +++ b/test/error.test.ts @@ -125,4 +125,24 @@ describe("error", () => { expect(ctx.errors[0].cause).toBeInstanceOf(CustomError); }); + + it("can parse statusCode from cause", async () => { + class HttpError extends Error { + statusCode = 400; + } + + class CustomError extends Error { + cause = new HttpError(); + } + + ctx.app.use( + "/", + eventHandler(() => { + throw createError(new CustomError()); + }), + ); + + const res = await ctx.request.get("/"); + expect(res.status).toBe(400); + }); }); From 7345ca7bec803f7803861f5448f907d11dda4e96 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Sun, 7 Jul 2024 17:26:09 +0200 Subject: [PATCH 2/4] simplify --- src/error.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/error.ts b/src/error.ts index b07373f7..ed669b38 100644 --- a/src/error.ts +++ b/src/error.ts @@ -117,18 +117,16 @@ export function createError( err.data = input.data; } - if (input.statusCode) { + const statusCode = + input.statusCode ?? + input.status ?? + (input?.cause as H3Error)?.statusCode ?? + (input?.cause as { status?: number })?.status; + + if (typeof statusCode === "number") { err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode); - } else if (input.status) { - err.statusCode = sanitizeStatusCode(input.status, err.statusCode); - } else if ( - typeof input.cause === "object" && - input.cause && - "statusCode" in input.cause && - typeof input.cause.statusCode === "number" - ) { - err.statusCode = sanitizeStatusCode(input.cause.statusCode, err.statusCode); } + if (input.statusMessage) { err.statusMessage = input.statusMessage; } else if (input.statusText) { From 0c75e012d529fe496d71133133605f9649f05791 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Sun, 7 Jul 2024 17:33:45 +0200 Subject: [PATCH 3/4] update --- src/error.ts | 37 +++++++++++++++++++++---------------- test/error.test.ts | 9 +++------ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/error.ts b/src/error.ts index ed669b38..784c25a8 100644 --- a/src/error.ts +++ b/src/error.ts @@ -93,8 +93,11 @@ export function createError( return input; } + // Inherit H3Error properties from cause as fallback + const cause: unknown = input.cause; + const err = new H3Error(input.message ?? input.statusMessage ?? "", { - cause: input.cause || input, + cause: cause || input, }); if (hasProp(input, "stack")) { @@ -120,27 +123,29 @@ export function createError( const statusCode = input.statusCode ?? input.status ?? - (input?.cause as H3Error)?.statusCode ?? - (input?.cause as { status?: number })?.status; - + (cause as H3Error)?.statusCode ?? + (cause as { status?: number })?.status; if (typeof statusCode === "number") { - err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode); + err.statusCode = sanitizeStatusCode(statusCode); } - if (input.statusMessage) { - err.statusMessage = input.statusMessage; - } else if (input.statusText) { - err.statusMessage = input.statusText as string; - } - if (err.statusMessage) { - err.statusMessage = sanitizeStatusMessage(err.statusMessage); + const statusMessage = + input.statusMessage ?? + input.statusText ?? + (cause as H3Error)?.statusMessage ?? + (cause as { statusText?: string })?.statusText; + if (statusMessage) { + err.statusMessage = sanitizeStatusMessage(statusMessage); } - if (input.fatal !== undefined) { - err.fatal = input.fatal; + const fatal = input.fatal ?? (cause as H3Error)?.fatal; + if (fatal !== undefined) { + err.fatal = fatal; } - if (input.unhandled !== undefined) { - err.unhandled = input.unhandled; + + const unhandled = input.unhandled ?? (cause as H3Error)?.unhandled; + if (unhandled !== undefined) { + err.unhandled = unhandled; } return err; diff --git a/test/error.test.ts b/test/error.test.ts index b1dfd3ee..c92146cd 100644 --- a/test/error.test.ts +++ b/test/error.test.ts @@ -113,12 +113,9 @@ describe("error", () => { cause = new HttpError(); } - ctx.app.use( - "/", - eventHandler(() => { - throw createError(new CustomError()); - }), - ); + ctx.app.use("/", () => { + throw createError(new CustomError()); + }); const res = await ctx.request.get("/"); expect(res.status).toBe(400); From 90b071b4b3d2bba0f7f2cfe98f72f250773ca620 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Sun, 7 Jul 2024 17:38:47 +0200 Subject: [PATCH 4/4] update test --- test/error.test.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/error.test.ts b/test/error.test.ts index c92146cd..8b1cfaa5 100644 --- a/test/error.test.ts +++ b/test/error.test.ts @@ -104,13 +104,14 @@ describe("error", () => { expect(ctx.errors[0].cause).toBeInstanceOf(CustomError); }); - it("can parse statusCode from cause", async () => { - class HttpError extends Error { - statusCode = 400; - } - + it("can inherit from cause", async () => { class CustomError extends Error { - cause = new HttpError(); + cause = createError({ + statusCode: 400, + statusMessage: "Bad Request", + unhandled: true, + fatal: true, + }); } ctx.app.use("/", () => { @@ -119,5 +120,7 @@ describe("error", () => { const res = await ctx.request.get("/"); expect(res.status).toBe(400); + expect(ctx.errors[0].unhandled).toBe(true); + expect(ctx.errors[0].fatal).toBe(true); }); });