@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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/commonjs/agent.d.ts +6 -0
  4. package/dist/commonjs/agent.js +16 -0
  5. package/dist/commonjs/app.d.ts +12 -0
  6. package/dist/commonjs/app.js +150 -0
  7. package/dist/commonjs/config/config.default.d.ts +27 -0
  8. package/dist/commonjs/config/config.default.js +15 -0
  9. package/dist/commonjs/index.d.ts +1 -0
  10. package/dist/commonjs/index.js +4 -0
  11. package/dist/commonjs/lib/error_view.d.ts +154 -0
  12. package/dist/commonjs/lib/error_view.js +248 -0
  13. package/dist/commonjs/lib/onerror_page.mustache.html +761 -0
  14. package/dist/commonjs/lib/utils.d.ts +10 -0
  15. package/dist/commonjs/lib/utils.js +53 -0
  16. package/dist/commonjs/package.json +3 -0
  17. package/dist/commonjs/types.d.ts +7 -0
  18. package/dist/commonjs/types.js +3 -0
  19. package/dist/esm/agent.d.ts +6 -0
  20. package/dist/esm/agent.js +13 -0
  21. package/dist/esm/app.d.ts +12 -0
  22. package/dist/esm/app.js +144 -0
  23. package/dist/esm/config/config.default.d.ts +27 -0
  24. package/dist/esm/config/config.default.js +10 -0
  25. package/dist/esm/index.d.ts +1 -0
  26. package/dist/esm/index.js +2 -0
  27. package/dist/esm/lib/error_view.d.ts +154 -0
  28. package/dist/esm/lib/error_view.js +241 -0
  29. package/dist/esm/lib/onerror_page.mustache.html +761 -0
  30. package/dist/esm/lib/utils.d.ts +10 -0
  31. package/dist/esm/lib/utils.js +43 -0
  32. package/dist/esm/package.json +3 -0
  33. package/dist/esm/types.d.ts +7 -0
  34. package/dist/esm/types.js +2 -0
  35. package/dist/package.json +4 -0
  36. package/package.json +93 -0
  37. package/src/agent.ts +12 -0
  38. package/src/app.ts +160 -0
  39. package/src/config/config.default.ts +34 -0
  40. package/src/index.ts +1 -0
  41. package/src/lib/error_view.ts +281 -0
  42. package/src/lib/onerror_page.mustache.html +761 -0
  43. package/src/lib/utils.ts +47 -0
  44. package/src/types.ts +12 -0
  45. 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,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,7 @@
1
+ import type { OnerrorConfig } from './config/config.default.js';
2
+ export type { OnerrorConfig };
3
+ declare module '@eggjs/core' {
4
+ interface EggAppConfig {
5
+ onerror: OnerrorConfig;
6
+ }
7
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,6 @@
1
+ import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
+ export default class Boot implements ILifecycleBoot {
3
+ private agent;
4
+ constructor(agent: EggCore);
5
+ didLoad(): Promise<void>;
6
+ }
@@ -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
+ }
@@ -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,2 @@
1
+ import './types.js';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxZQUFZLENBQUMifQ==
@@ -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
+ }