koa-onerror
Version:
koa error handler, hack ctx.onerror
161 lines • 12.4 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.onerror = onerror;
const node_http_1 = __importDefault(require("node:http"));
const node_path_1 = __importDefault(require("node:path"));
const node_fs_1 = __importDefault(require("node:fs"));
const node_url_1 = require("node:url");
const node_util_1 = require("node:util");
const escape_html_1 = __importDefault(require("escape-html"));
const stream_wormhole_1 = require("stream-wormhole");
const debug = (0, node_util_1.debuglog)('koa-onerror');
const defaultOptions = {
text,
json,
html,
};
function onerror(app, options) {
options = { ...defaultOptions, ...options };
app.context.onerror = function (err) {
debug('onerror: %s', err);
// don't do anything if there is no error.
// this allows you to pass `this.onerror`
// to node-style callbacks.
if (err == null) {
return;
}
// ignore all padding request stream
if (this.req) {
(0, stream_wormhole_1.sendToWormhole)(this.req);
debug('send the req to wormhole');
}
// wrap non-error object
if (!(err instanceof Error)) {
debug('err is not an instance of Error');
let errMsg = err;
if (typeof err === 'object') {
try {
errMsg = JSON.stringify(err);
}
catch (e) {
debug('stringify error: %s', e);
errMsg = (0, node_util_1.format)('%s', e);
}
}
const newError = new Error('non-error thrown: ' + errMsg);
// err maybe an object, try to copy the name, message and stack to the new error instance
if (err) {
if (err.name)
newError.name = err.name;
if (err.message)
newError.message = err.message;
if (err.stack)
newError.stack = err.stack;
if (err.status) {
Reflect.set(newError, 'status', err.status);
}
if (err.headers) {
Reflect.set(newError, 'headers', err.headers);
}
}
err = newError;
debug('wrap err: %s', err);
}
const headerSent = this.headerSent || !this.writable;
if (headerSent) {
debug('headerSent is true');
err.headerSent = true;
}
// delegate
this.app.emit('error', err, this);
// nothing we can do here other
// than delegate to the app-level
// handler and log.
if (headerSent)
return;
// ENOENT support
if (err.code === 'ENOENT') {
err.status = 404;
}
if (typeof err.status !== 'number' || !node_http_1.default.STATUS_CODES[err.status]) {
err.status = 500;
}
this.status = err.status;
this.set(err.headers);
let type = 'text';
if (options.accepts) {
type = options.accepts.call(this, 'html', 'text', 'json');
}
else {
type = this.accepts('html', 'text', 'json');
}
debug('accepts type: %s', type);
type = type || 'text';
if (options.all) {
options.all.call(this, err, this);
}
else {
if (options.redirect && type !== 'json') {
this.redirect(options.redirect);
}
else {
options[type].call(this, err, this);
this.type = type;
}
}
if (type === 'json') {
this.body = JSON.stringify(this.body);
}
debug('end the response, body: %s', this.body);
this.res.end(this.body);
};
return app;
}
const devTemplate = node_fs_1.default.readFileSync(node_path_1.default.join(getSourceDirname(), 'templates/dev_error.html'), 'utf8');
const prodTemplate = node_fs_1.default.readFileSync(node_path_1.default.join(getSourceDirname(), 'templates/prod_error.html'), 'utf8');
function isDev() {
return !process.env.NODE_ENV || process.env.NODE_ENV === 'development';
}
/**
* default text error handler
*/
function text(err, ctx) {
// unset all headers, and set those specified
ctx.res._headers = {};
ctx.set(err.headers);
ctx.body = (isDev() || err.expose) && err.message
? err.message
: node_http_1.default.STATUS_CODES[ctx.status];
}
/**
* default json error handler
*/
function json(err, ctx) {
const message = (isDev() || err.expose) && err.message
? err.message
: node_http_1.default.STATUS_CODES[ctx.status];
ctx.body = { error: message };
}
/**
* default html error handler
*/
function html(err, ctx) {
const template = isDev() ? devTemplate : prodTemplate;
ctx.body = template
.replace('{{status}}', (0, escape_html_1.default)(String(err.status)))
.replace('{{stack}}', (0, escape_html_1.default)(err.stack));
ctx.type = 'html';
}
function getSourceDirname() {
if (typeof __dirname === 'string') {
return __dirname;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const __filename = (0, node_url_1.fileURLToPath)('import_meta_url_placeholder_by_tshy_after');
return node_path_1.default.dirname(__filename);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFrQ0EsMEJBbUdDO0FBcklELDBEQUE2QjtBQUM3QiwwREFBNkI7QUFDN0Isc0RBQXlCO0FBQ3pCLHVDQUF5QztBQUN6Qyx5Q0FBNkM7QUFDN0MsOERBQXFDO0FBQ3JDLHFEQUFpRDtBQUVqRCxNQUFNLEtBQUssR0FBRyxJQUFBLG9CQUFRLEVBQUMsYUFBYSxDQUFDLENBQUM7QUFvQnRDLE1BQU0sY0FBYyxHQUFtQjtJQUNyQyxJQUFJO0lBQ0osSUFBSTtJQUNKLElBQUk7Q0FDTCxDQUFDO0FBRUYsU0FBZ0IsT0FBTyxDQUFDLEdBQVEsRUFBRSxPQUF3QjtJQUN4RCxPQUFPLEdBQUcsRUFBRSxHQUFHLGNBQWMsRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDO0lBRTVDLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxHQUFHLFVBQVMsR0FBUTtRQUNyQyxLQUFLLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzFCLDBDQUEwQztRQUMxQyx5Q0FBeUM7UUFDekMsMkJBQTJCO1FBQzNCLElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ2hCLE9BQU87UUFDVCxDQUFDO1FBRUQsb0NBQW9DO1FBQ3BDLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBQSxnQ0FBYyxFQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN6QixLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBRUQsd0JBQXdCO1FBQ3hCLElBQUksQ0FBQyxDQUFDLEdBQUcsWUFBWSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVCLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBQ3pDLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQztZQUNqQixJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEs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