@eggjs/onerror 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/commonjs/agent.d.ts +6 -0
- package/dist/commonjs/agent.js +16 -0
- package/dist/commonjs/app.d.ts +12 -0
- package/dist/commonjs/app.js +150 -0
- package/dist/commonjs/config/config.default.d.ts +27 -0
- package/dist/commonjs/config/config.default.js +15 -0
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.js +4 -0
- package/dist/commonjs/lib/error_view.d.ts +154 -0
- package/dist/commonjs/lib/error_view.js +248 -0
- package/dist/commonjs/lib/onerror_page.mustache.html +761 -0
- package/dist/commonjs/lib/utils.d.ts +10 -0
- package/dist/commonjs/lib/utils.js +53 -0
- package/dist/commonjs/package.json +3 -0
- package/dist/commonjs/types.d.ts +7 -0
- package/dist/commonjs/types.js +3 -0
- package/dist/esm/agent.d.ts +6 -0
- package/dist/esm/agent.js +13 -0
- package/dist/esm/app.d.ts +12 -0
- package/dist/esm/app.js +144 -0
- package/dist/esm/config/config.default.d.ts +27 -0
- package/dist/esm/config/config.default.js +10 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/lib/error_view.d.ts +154 -0
- package/dist/esm/lib/error_view.js +241 -0
- package/dist/esm/lib/onerror_page.mustache.html +761 -0
- package/dist/esm/lib/utils.d.ts +10 -0
- package/dist/esm/lib/utils.js +43 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/types.d.ts +7 -0
- package/dist/esm/types.js +2 -0
- package/dist/package.json +4 -0
- package/package.json +93 -0
- package/src/agent.ts +12 -0
- package/src/app.ts +160 -0
- package/src/config/config.default.ts +34 -0
- package/src/index.ts +1 -0
- package/src/lib/error_view.ts +281 -0
- package/src/lib/onerror_page.mustache.html +761 -0
- package/src/lib/utils.ts +47 -0
- package/src/types.ts +12 -0
- package/src/typings/index.d.ts +4 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Context, EggCore } from '@eggjs/core';
|
|
2
|
+
import type { OnerrorError } from 'koa-onerror';
|
|
3
|
+
export declare function detectErrorMessage(ctx: Context, err: OnerrorError): string;
|
|
4
|
+
export declare function detectStatus(err: OnerrorError): number;
|
|
5
|
+
export declare function accepts(ctx: Context): "json" | "js" | "html";
|
|
6
|
+
export declare function isProd(app: EggCore): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Get the source directory name
|
|
9
|
+
*/
|
|
10
|
+
export declare function getSourceDirname(): string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.detectErrorMessage = detectErrorMessage;
|
|
7
|
+
exports.detectStatus = detectStatus;
|
|
8
|
+
exports.accepts = accepts;
|
|
9
|
+
exports.isProd = isProd;
|
|
10
|
+
exports.getSourceDirname = getSourceDirname;
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const node_url_1 = require("node:url");
|
|
13
|
+
function detectErrorMessage(ctx, err) {
|
|
14
|
+
// detect json parse error
|
|
15
|
+
if (err.status === 400 &&
|
|
16
|
+
err.name === 'SyntaxError' &&
|
|
17
|
+
ctx.request.is('application/json', 'application/vnd.api+json', 'application/csp-report')) {
|
|
18
|
+
return 'Problems parsing JSON';
|
|
19
|
+
}
|
|
20
|
+
return err.message;
|
|
21
|
+
}
|
|
22
|
+
function detectStatus(err) {
|
|
23
|
+
// detect status
|
|
24
|
+
let status = err.status || 500;
|
|
25
|
+
if (status < 200) {
|
|
26
|
+
// invalid status consider as 500, like urllib will return -1 status
|
|
27
|
+
status = 500;
|
|
28
|
+
}
|
|
29
|
+
return status;
|
|
30
|
+
}
|
|
31
|
+
function accepts(ctx) {
|
|
32
|
+
if (ctx.acceptJSON)
|
|
33
|
+
return 'json';
|
|
34
|
+
if (ctx.acceptJSONP)
|
|
35
|
+
return 'js';
|
|
36
|
+
return 'html';
|
|
37
|
+
}
|
|
38
|
+
function isProd(app) {
|
|
39
|
+
return app.config.env !== 'local' && app.config.env !== 'unittest';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the source directory name
|
|
43
|
+
*/
|
|
44
|
+
function getSourceDirname() {
|
|
45
|
+
if (typeof __dirname === 'string') {
|
|
46
|
+
return node_path_1.default.dirname(__dirname);
|
|
47
|
+
}
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
const __filename = (0, node_url_1.fileURLToPath)('import_meta_url_placeholder_by_tshy_after');
|
|
51
|
+
return node_path_1.default.dirname(node_path_1.default.dirname(__filename));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBS0EsZ0RBUUM7QUFFRCxvQ0FRQztBQUVELDBCQUlDO0FBRUQsd0JBRUM7QUFLRCw0Q0FRQztBQTlDRCwwREFBNkI7QUFDN0IsdUNBQXlDO0FBSXpDLFNBQWdCLGtCQUFrQixDQUFDLEdBQVksRUFBRSxHQUFpQjtJQUNoRSwwQkFBMEI7SUFDMUIsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEdBQUc7UUFDbEIsR0FBRyxDQUFDLElBQUksS0FBSyxhQUFhO1FBQzFCLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLGtCQUFrQixFQUFFLDBCQUEwQixFQUFFLHdCQUF3QixDQUFDLEVBQUUsQ0FBQztRQUM3RixPQUFPLHVCQUF1QixDQUFDO0lBQ2pDLENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUM7QUFDckIsQ0FBQztBQUVELFNBQWdCLFlBQVksQ0FBQyxHQUFpQjtJQUM1QyxnQkFBZ0I7SUFDaEIsSUFBSSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sSUFBSSxHQUFHLENBQUM7SUFDL0IsSUFBSSxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDakIsb0VBQW9FO1FBQ3BFLE1BQU0sR0FBRyxHQUFHLENBQUM7SUFDZixDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELFNBQWdCLE9BQU8sQ0FBQyxHQUFZO0lBQ2xDLElBQUksR0FBRyxDQUFDLFVBQVU7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUNsQyxJQUFJLEdBQUcsQ0FBQyxXQUFXO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDakMsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELFNBQWdCLE1BQU0sQ0FBQyxHQUFZO0lBQ2pDLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEtBQUssT0FBTyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxLQUFLLFVBQVUsQ0FBQztBQUNyRSxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixnQkFBZ0I7SUFDOUIsSUFBSSxPQUFPLFNBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNsQyxPQUFPLG1CQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFDRCw2REFBNkQ7SUFDN0QsYUFBYTtJQUNiLE1BQU0sVUFBVSxHQUFHLElBQUEsd0JBQWEsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2xELE9BQU8sbUJBQUksQ0FBQyxPQUFPLENBQUMsbUJBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUNoRCxDQUFDIn0=
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default class Boot {
|
|
2
|
+
agent;
|
|
3
|
+
constructor(agent) {
|
|
4
|
+
this.agent = agent;
|
|
5
|
+
}
|
|
6
|
+
async didLoad() {
|
|
7
|
+
// should watch error event
|
|
8
|
+
this.agent.on('error', err => {
|
|
9
|
+
this.agent.coreLogger.error(err);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWdlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxDQUFDLE9BQU8sT0FBTyxJQUFJO0lBQ0g7SUFBcEIsWUFBb0IsS0FBYztRQUFkLFVBQUssR0FBTCxLQUFLLENBQVM7SUFBRyxDQUFDO0lBRXRDLEtBQUssQ0FBQyxPQUFPO1FBQ1gsMkJBQTJCO1FBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsRUFBRTtZQUMzQixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YifQ==
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type OnerrorError } from 'koa-onerror';
|
|
2
|
+
import type { ILifecycleBoot, EggCore } from '@eggjs/core';
|
|
3
|
+
export interface OnerrorErrorWithCode extends OnerrorError {
|
|
4
|
+
code?: string;
|
|
5
|
+
type?: string;
|
|
6
|
+
errors?: any[];
|
|
7
|
+
}
|
|
8
|
+
export default class Boot implements ILifecycleBoot {
|
|
9
|
+
private app;
|
|
10
|
+
constructor(app: EggCore);
|
|
11
|
+
didLoad(): Promise<void>;
|
|
12
|
+
}
|
package/dist/esm/app.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { onerror } from 'koa-onerror';
|
|
4
|
+
import { ErrorView } from './lib/error_view.js';
|
|
5
|
+
import { isProd, detectStatus, detectErrorMessage, accepts } from './lib/utils.js';
|
|
6
|
+
export default class Boot {
|
|
7
|
+
app;
|
|
8
|
+
constructor(app) {
|
|
9
|
+
this.app = app;
|
|
10
|
+
}
|
|
11
|
+
async didLoad() {
|
|
12
|
+
// logging error
|
|
13
|
+
const config = this.app.config.onerror;
|
|
14
|
+
const viewTemplate = fs.readFileSync(config.templatePath, 'utf8');
|
|
15
|
+
const app = this.app;
|
|
16
|
+
app.on('error', (err, ctx) => {
|
|
17
|
+
if (!ctx) {
|
|
18
|
+
ctx = app.currentContext || app.createAnonymousContext();
|
|
19
|
+
}
|
|
20
|
+
if (config.appErrorFilter && !config.appErrorFilter(err, ctx))
|
|
21
|
+
return;
|
|
22
|
+
const status = detectStatus(err);
|
|
23
|
+
// 5xx
|
|
24
|
+
if (status >= 500) {
|
|
25
|
+
try {
|
|
26
|
+
ctx.logger.error(err);
|
|
27
|
+
}
|
|
28
|
+
catch (ex) {
|
|
29
|
+
app.logger.error(err);
|
|
30
|
+
app.logger.error(ex);
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// 4xx
|
|
35
|
+
try {
|
|
36
|
+
ctx.logger.warn(err);
|
|
37
|
+
}
|
|
38
|
+
catch (ex) {
|
|
39
|
+
app.logger.warn(err);
|
|
40
|
+
app.logger.error(ex);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const errorOptions = {
|
|
44
|
+
// support customize accepts function
|
|
45
|
+
accepts() {
|
|
46
|
+
const fn = config.accepts || accepts;
|
|
47
|
+
return fn(this);
|
|
48
|
+
},
|
|
49
|
+
html(err, ctx) {
|
|
50
|
+
const status = detectStatus(err);
|
|
51
|
+
const errorPageUrl = typeof config.errorPageUrl === 'function'
|
|
52
|
+
? config.errorPageUrl(err, ctx)
|
|
53
|
+
: config.errorPageUrl;
|
|
54
|
+
// keep the real response status
|
|
55
|
+
ctx.realStatus = status;
|
|
56
|
+
// don't respond any error message in production env
|
|
57
|
+
if (isProd(app)) {
|
|
58
|
+
// 5xx
|
|
59
|
+
if (status >= 500) {
|
|
60
|
+
if (errorPageUrl) {
|
|
61
|
+
const statusQuery = (errorPageUrl.indexOf('?') > 0 ? '&' : '?') +
|
|
62
|
+
`real_status=${status}`;
|
|
63
|
+
return ctx.redirect(errorPageUrl + statusQuery);
|
|
64
|
+
}
|
|
65
|
+
ctx.status = 500;
|
|
66
|
+
ctx.body = `<h2>Internal Server Error, real status: ${status}</h2>`;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// 4xx
|
|
70
|
+
ctx.status = status;
|
|
71
|
+
ctx.body = `<h2>${status} ${http.STATUS_CODES[status]}</h2>`;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// show simple error format for unittest
|
|
75
|
+
if (app.config.env === 'unittest') {
|
|
76
|
+
ctx.status = status;
|
|
77
|
+
ctx.body = `${err.name}: ${err.message}\n${err.stack}`;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const errorView = new ErrorView(ctx, err, viewTemplate);
|
|
81
|
+
ctx.body = errorView.toHTML();
|
|
82
|
+
},
|
|
83
|
+
json(err, ctx) {
|
|
84
|
+
const status = detectStatus(err);
|
|
85
|
+
let errorJson = {};
|
|
86
|
+
ctx.status = status;
|
|
87
|
+
const code = err.code ?? err.type;
|
|
88
|
+
const message = detectErrorMessage(ctx, err);
|
|
89
|
+
if (isProd(app)) {
|
|
90
|
+
// 5xx server side error
|
|
91
|
+
if (status >= 500) {
|
|
92
|
+
errorJson = {
|
|
93
|
+
code,
|
|
94
|
+
// don't respond any error message in production env
|
|
95
|
+
message: http.STATUS_CODES[status],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// 4xx client side error
|
|
100
|
+
// addition `errors`
|
|
101
|
+
errorJson = {
|
|
102
|
+
code,
|
|
103
|
+
message,
|
|
104
|
+
errors: err.errors,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
errorJson = {
|
|
110
|
+
code,
|
|
111
|
+
message,
|
|
112
|
+
errors: err.errors,
|
|
113
|
+
};
|
|
114
|
+
if (status >= 500) {
|
|
115
|
+
// provide detail error stack in local env
|
|
116
|
+
errorJson.stack = err.stack;
|
|
117
|
+
errorJson.name = err.name;
|
|
118
|
+
for (const key in err) {
|
|
119
|
+
if (!errorJson[key]) {
|
|
120
|
+
errorJson[key] = err[key];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
ctx.body = errorJson;
|
|
126
|
+
},
|
|
127
|
+
js(err, ctx) {
|
|
128
|
+
errorOptions.json.call(ctx, err, ctx);
|
|
129
|
+
if (ctx.createJsonpBody) {
|
|
130
|
+
ctx.createJsonpBody(ctx.body);
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
// support customize error response
|
|
135
|
+
const keys = ['all', 'html', 'json', 'text', 'js'];
|
|
136
|
+
for (const type of keys) {
|
|
137
|
+
if (config[type]) {
|
|
138
|
+
Reflect.set(errorOptions, type, config[type]);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
onerror(app, errorOptions);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3pCLE9BQU8sRUFBRSxPQUFPLEVBQTBDLE1BQU0sYUFBYSxDQUFDO0FBRTlFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQVNuRixNQUFNLENBQUMsT0FBTyxPQUFPLElBQUk7SUFDSDtJQUFwQixZQUFvQixHQUFZO1FBQVosUUFBRyxHQUFILEdBQUcsQ0FBUztJQUFHLENBQUM7SUFFcEMsS0FBSyxDQUFDLE9BQU87UUFDWCxnQkFBZ0I7UUFDaEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQ3ZDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNsRSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ3JCLEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQzNCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDVCxHQUFHLEdBQUcsR0FBRyxDQUFDLGNBQWMsSUFBSSxHQUFHLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUMzRCxDQUFDO1lBQ0QsSUFBSSxNQUFNLENBQUMsY0FBYyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDO2dCQUFFLE9BQU87WUFFdEUsTUFBTSxNQUFNLEdBQUcsWUFB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
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Context } from '@eggjs/core';
|
|
2
|
+
import type { OnerrorError, OnerrorOptions } from 'koa-onerror';
|
|
3
|
+
export interface OnerrorConfig extends OnerrorOptions {
|
|
4
|
+
/**
|
|
5
|
+
* 5xx error will redirect to ${errorPageUrl}
|
|
6
|
+
* won't redirect in local env
|
|
7
|
+
*
|
|
8
|
+
* Default: `''`
|
|
9
|
+
*/
|
|
10
|
+
errorPageUrl: string | ((err: OnerrorError, ctx: Context) => string);
|
|
11
|
+
/**
|
|
12
|
+
* will execute `appErrorFilter` when emit an error in `app`
|
|
13
|
+
* If `appErrorFilter` return false, egg-onerror won't log this error.
|
|
14
|
+
* You can logging in `appErrorFilter` and return false to override the default error logging.
|
|
15
|
+
*
|
|
16
|
+
* Default: `undefined`
|
|
17
|
+
*/
|
|
18
|
+
appErrorFilter?: (err: OnerrorError, ctx: Context) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* default template path
|
|
21
|
+
*/
|
|
22
|
+
templatePath: string;
|
|
23
|
+
}
|
|
24
|
+
declare const _default: {
|
|
25
|
+
onerror: OnerrorConfig;
|
|
26
|
+
};
|
|
27
|
+
export default _default;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { getSourceDirname } from '../lib/utils.js';
|
|
3
|
+
export default {
|
|
4
|
+
onerror: {
|
|
5
|
+
errorPageUrl: '',
|
|
6
|
+
appErrorFilter: undefined,
|
|
7
|
+
templatePath: path.join(getSourceDirname(), 'lib/onerror_page.mustache.html'),
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmRlZmF1bHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL2NvbmZpZy5kZWZhdWx0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUc3QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQXdCbkQsZUFBZTtJQUNiLE9BQU8sRUFBRTtRQUNQLFlBQVksRUFBRSxFQUFFO1FBQ2hCLGNBQWMsRUFBRSxTQUFTO1FBQ3pCLFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsZ0NBQWdDLENBQUM7S0FDN0Q7Q0FDbkIsQ0FBQyJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './types.js';
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { type StackFrame } from 'stack-trace';
|
|
2
|
+
import type { OnerrorError } from 'koa-onerror';
|
|
3
|
+
import type { Context } from '@eggjs/core';
|
|
4
|
+
export interface FrameSource {
|
|
5
|
+
pre: string[];
|
|
6
|
+
line: string;
|
|
7
|
+
post: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface Frame extends StackFrame {
|
|
10
|
+
context?: FrameSource;
|
|
11
|
+
}
|
|
12
|
+
export declare class ErrorView {
|
|
13
|
+
ctx: Context;
|
|
14
|
+
error: OnerrorError;
|
|
15
|
+
request: Context['request'];
|
|
16
|
+
app: Context['app'];
|
|
17
|
+
assets: Map<string, string>;
|
|
18
|
+
viewTemplate: string;
|
|
19
|
+
codeContext: number;
|
|
20
|
+
_filterHeaders: string[];
|
|
21
|
+
constructor(ctx: Context, error: OnerrorError, template: string);
|
|
22
|
+
/**
|
|
23
|
+
* get html error page
|
|
24
|
+
*
|
|
25
|
+
* @return {String} html page
|
|
26
|
+
*/
|
|
27
|
+
toHTML(): string;
|
|
28
|
+
/**
|
|
29
|
+
* compile view
|
|
30
|
+
*
|
|
31
|
+
* @param {String} tpl - template
|
|
32
|
+
* @param {Object} locals - data used by template
|
|
33
|
+
*/
|
|
34
|
+
compileView(tpl: string, locals: Record<string, unknown>): string;
|
|
35
|
+
/**
|
|
36
|
+
* check if the frame is node native file.
|
|
37
|
+
*
|
|
38
|
+
* @param {Frame} frame - current frame
|
|
39
|
+
*/
|
|
40
|
+
isNode(frame: Frame): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* check if the frame is app modules.
|
|
43
|
+
*
|
|
44
|
+
* @param {Object} frame - current frame
|
|
45
|
+
*/
|
|
46
|
+
isApp(frame: Frame): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* cache file asserts
|
|
49
|
+
*
|
|
50
|
+
* @param {String} key - assert key
|
|
51
|
+
* @param {String} value - assert content
|
|
52
|
+
*/
|
|
53
|
+
setAssets(key: string, value: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* get cache file asserts
|
|
56
|
+
*
|
|
57
|
+
* @param {String} key - assert key
|
|
58
|
+
*/
|
|
59
|
+
getAssets(key: string): string | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* get frame source
|
|
62
|
+
*
|
|
63
|
+
* @param {Object} frame - current frame
|
|
64
|
+
*/
|
|
65
|
+
getFrameSource(frame: StackFrame): FrameSource;
|
|
66
|
+
/**
|
|
67
|
+
* parse error and return frame stack
|
|
68
|
+
*/
|
|
69
|
+
parseError(): Frame[];
|
|
70
|
+
/**
|
|
71
|
+
* get stack context
|
|
72
|
+
*
|
|
73
|
+
* @param {Object} frame - current frame
|
|
74
|
+
*/
|
|
75
|
+
getContext(frame: Frame): {
|
|
76
|
+
start?: undefined;
|
|
77
|
+
pre?: undefined;
|
|
78
|
+
line?: undefined;
|
|
79
|
+
post?: undefined;
|
|
80
|
+
} | {
|
|
81
|
+
start: number;
|
|
82
|
+
pre: string;
|
|
83
|
+
line: string;
|
|
84
|
+
post: string;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* get frame classes, let view identify the frame
|
|
88
|
+
*
|
|
89
|
+
* @param {any} frame - current frame
|
|
90
|
+
* @param {any} index - current index
|
|
91
|
+
*/
|
|
92
|
+
getFrameClasses(frame: Frame, index: number): string;
|
|
93
|
+
/**
|
|
94
|
+
* serialize frame and return meaningful data
|
|
95
|
+
*
|
|
96
|
+
* @param {Object} frame - current frame
|
|
97
|
+
*/
|
|
98
|
+
serializeFrame(frame: Frame): {
|
|
99
|
+
extname: string;
|
|
100
|
+
file: string;
|
|
101
|
+
method: string;
|
|
102
|
+
line: number;
|
|
103
|
+
column: number;
|
|
104
|
+
context: {
|
|
105
|
+
start?: undefined;
|
|
106
|
+
pre?: undefined;
|
|
107
|
+
line?: undefined;
|
|
108
|
+
post?: undefined;
|
|
109
|
+
} | {
|
|
110
|
+
start: number;
|
|
111
|
+
pre: string;
|
|
112
|
+
line: string;
|
|
113
|
+
post: string;
|
|
114
|
+
};
|
|
115
|
+
classes: string;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* serialize base data
|
|
119
|
+
*
|
|
120
|
+
* @param {Object} stack - frame stack
|
|
121
|
+
* @param {Function} frameFormatter - frame formatter function
|
|
122
|
+
*/
|
|
123
|
+
serializeData(stack: Frame[], frameFormatter: (frame: Frame, index: number) => any): {
|
|
124
|
+
code: any;
|
|
125
|
+
message: string;
|
|
126
|
+
name: string;
|
|
127
|
+
status: number;
|
|
128
|
+
frames: any[];
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* serialize request object
|
|
132
|
+
*/
|
|
133
|
+
serializeRequest(): {
|
|
134
|
+
url: string;
|
|
135
|
+
httpVersion: string;
|
|
136
|
+
method: string;
|
|
137
|
+
connection: string | undefined;
|
|
138
|
+
headers: {
|
|
139
|
+
key: string;
|
|
140
|
+
value: string | string[] | undefined;
|
|
141
|
+
}[];
|
|
142
|
+
cookies: {
|
|
143
|
+
key: string;
|
|
144
|
+
value: string | undefined;
|
|
145
|
+
}[];
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* serialize app info object
|
|
149
|
+
*/
|
|
150
|
+
serializeAppInfo(): {
|
|
151
|
+
baseDir: string;
|
|
152
|
+
config: string;
|
|
153
|
+
};
|
|
154
|
+
}
|