@eggjs/onerror
Version:
error handler for egg
144 lines • 11.4 kB
JavaScript
import http from 'node:http';
import fs from 'node:fs';
import { onerror } from 'koa-onerror';
import { ErrorView } from './lib/error_view.js';
import { isProd, detectStatus, detectErrorMessage, accepts } from './lib/utils.js';
export default class Boot {
app;
constructor(app) {
this.app = app;
}
async didLoad() {
// logging error
const config = this.app.config.onerror;
const viewTemplate = fs.readFileSync(config.templatePath, 'utf8');
const app = this.app;
app.on('error', (err, ctx) => {
if (!ctx) {
ctx = app.currentContext || app.createAnonymousContext();
}
if (config.appErrorFilter && !config.appErrorFilter(err, ctx))
return;
const status = detectStatus(err);
// 5xx
if (status >= 500) {
try {
ctx.logger.error(err);
}
catch (ex) {
app.logger.error(err);
app.logger.error(ex);
}
return;
}
// 4xx
try {
ctx.logger.warn(err);
}
catch (ex) {
app.logger.warn(err);
app.logger.error(ex);
}
});
const errorOptions = {
// support customize accepts function
accepts() {
const fn = config.accepts || accepts;
return fn(this);
},
html(err, ctx) {
const status = detectStatus(err);
const errorPageUrl = typeof config.errorPageUrl === 'function'
? config.errorPageUrl(err, ctx)
: config.errorPageUrl;
// keep the real response status
ctx.realStatus = status;
// don't respond any error message in production env
if (isProd(app)) {
// 5xx
if (status >= 500) {
if (errorPageUrl) {
const statusQuery = (errorPageUrl.indexOf('?') > 0 ? '&' : '?') +
`real_status=${status}`;
return ctx.redirect(errorPageUrl + statusQuery);
}
ctx.status = 500;
ctx.body = `<h2>Internal Server Error, real status: ${status}</h2>`;
return;
}
// 4xx
ctx.status = status;
ctx.body = `<h2>${status} ${http.STATUS_CODES[status]}</h2>`;
return;
}
// show simple error format for unittest
if (app.config.env === 'unittest') {
ctx.status = status;
ctx.body = `${err.name}: ${err.message}\n${err.stack}`;
return;
}
const errorView = new ErrorView(ctx, err, viewTemplate);
ctx.body = errorView.toHTML();
},
json(err, ctx) {
const status = detectStatus(err);
let errorJson = {};
ctx.status = status;
const code = err.code ?? err.type;
const message = detectErrorMessage(ctx, err);
if (isProd(app)) {
// 5xx server side error
if (status >= 500) {
errorJson = {
code,
// don't respond any error message in production env
message: http.STATUS_CODES[status],
};
}
else {
// 4xx client side error
// addition `errors`
errorJson = {
code,
message,
errors: err.errors,
};
}
}
else {
errorJson = {
code,
message,
errors: err.errors,
};
if (status >= 500) {
// provide detail error stack in local env
errorJson.stack = err.stack;
errorJson.name = err.name;
for (const key in err) {
if (!errorJson[key]) {
errorJson[key] = err[key];
}
}
}
}
ctx.body = errorJson;
},
js(err, ctx) {
errorOptions.json.call(ctx, err, ctx);
if (ctx.createJsonpBody) {
ctx.createJsonpBody(ctx.body);
}
},
};
// support customize error response
const keys = ['all', 'html', 'json', 'text', 'js'];
for (const type of keys) {
if (config[type]) {
Reflect.set(errorOptions, type, config[type]);
}
}
onerror(app, errorOptions);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3pCLE9BQU8sRUFBRSxPQUFPLEVBQTBDLE1BQU0sYUFBYSxDQUFDO0FBRTlFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQVNuRixNQUFNLENBQUMsT0FBTyxPQUFPLElBQUk7SUFDSDtJQUFwQixZQUFvQixHQUFZO1FBQVosUUFBRyxHQUFILEdBQUcsQ0FBUztJQUFHLENBQUM7SUFFcEMsS0FBSyxDQUFDLE9BQU87UUFDWCxnQkFBZ0I7UUFDaEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQ3ZDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNsRSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ3JCLEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQzNCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDVCxHQUFHLEdBQUcsR0FBRyxDQUFDLGNBQWMsSUFBSSxHQUFHLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUMzRCxDQUFDO1lBQ0QsSUFBSSxNQUFNLENBQUMsY0FBYyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDO2dCQUFFLE9BQU87WUFFdEUsTUFBTSxNQUFNLEdBQUcsWUFB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