diff --git a/server/onerror.ts b/server/onerror.ts index 5846123b3..c167b2b1d 100644 --- a/server/onerror.ts +++ b/server/onerror.ts @@ -14,10 +14,7 @@ let errorHtmlCache: Buffer | undefined; const readErrorFile = (): Buffer => { if (isDev) { - return ( - errorHtmlCache ?? - (errorHtmlCache = fs.readFileSync(path.join(__dirname, "error.dev.html"))) - ); + return fs.readFileSync(path.join(__dirname, "error.dev.html")); } if (isProd) { @@ -82,10 +79,27 @@ export default function onerror(app: Koa) { err = newError; } - if (err.code === "ENOENT") { + if (err instanceof ValidationError) { + // @ts-expect-error status is not a property on ValidationError + err.status = 400; + + if (err.errors && err.errors[0]) { + err.message = `${err.errors[0].message} (${err.errors[0].path})`; + } + } + + if ( + err.code === "ENOENT" || + err instanceof EmptyResultError || + /Not found/i.test(err.message) + ) { err.status = 404; } + if (/Authorization error/i.test(err.message)) { + err.status = 403; + } + if (typeof err.status !== "number" || !http.STATUS_CODES[err.status]) { err.status = 500; } @@ -134,47 +148,37 @@ export default function onerror(app: Koa) { function json(err: any, ctx: Context) { ctx.status = err.status; - let message = err.message || err.name; - let error; + let message; + let id; - if (err instanceof ValidationError) { - // super basic form error handling - ctx.status = 400; - - if (err.errors && err.errors[0]) { - message = `${err.errors[0].message} (${err.errors[0].path})`; - } + if (ctx.status === 400) { + message = "Validation error"; + id = "validation_error"; } - - if (err instanceof EmptyResultError || /Not found/i.test(message)) { + if (ctx.status === 401) { + message = "Authentication error"; + id = "authentication_error"; + } + if (ctx.status === 403) { + message = "Authorization error"; + id = "authorization_error"; + } + if (ctx.status === 404) { message = "Resource not found"; - ctx.status = 404; - error = "not_found"; + id = "not_found"; } - - if (/Authorization error/i.test(message)) { - ctx.status = 403; - error = "authorization_error"; - } - if (ctx.status === 500) { message = "Internal server error"; - error = "internal_server_error"; + id = "internal_server_error"; } ctx.body = { ok: false, - error: snakeCase(err.id || error), + error: snakeCase(err.id || id), status: ctx.status, - message, - data: err.errorData, + message: err.message || message || err.name, + data: err.errorData ?? undefined, }; - - // @ts-expect-error ts-migrate(2571) FIXME: Object is of type 'unknown'. - if (!ctx.body.data) { - // @ts-expect-error ts-migrate(2571) FIXME: Object is of type 'unknown'. - delete ctx.body.data; - } } /** @@ -188,6 +192,7 @@ function html(err: any, ctx: Context) { const page = readErrorFile(); ctx.body = page .toString() + .replace(/\/\/inject-message\/\//g, escape(err.message)) .replace(/\/\/inject-status\/\//g, escape(err.status)) .replace(/\/\/inject-stack\/\//g, escape(err.stack)); ctx.type = "html"; diff --git a/server/routes/api/__snapshots__/groups.test.ts.snap b/server/routes/api/__snapshots__/groups.test.ts.snap index 9530d3a94..e53139afc 100644 --- a/server/routes/api/__snapshots__/groups.test.ts.snap +++ b/server/routes/api/__snapshots__/groups.test.ts.snap @@ -83,7 +83,7 @@ Object { exports[`#groups.update when user is admin fails with validation error when name already taken 1`] = ` Object { - "error": "", + "error": "validation_error", "message": "The name of this group is already in use (isUniqueNameInTeam)", "ok": false, "status": 400, diff --git a/server/static/error.dev.html b/server/static/error.dev.html index 917a102eb..cd8eba10c 100644 --- a/server/static/error.dev.html +++ b/server/static/error.dev.html @@ -2,33 +2,44 @@ Error - //inject-status// - +
-

Error

-

Looks like something broke!

-
-        
-//inject-stack//
-        
-      
+

//inject-status//

+

//inject-message//

+
//inject-stack//
diff --git a/server/static/error.prod.html b/server/static/error.prod.html index d47030178..4d4f19808 100644 --- a/server/static/error.prod.html +++ b/server/static/error.prod.html @@ -2,28 +2,36 @@ Error - //inject-status// - +
-

Error

-

Looks like something broke!

+

//inject-status//

+

//inject-message//