@eggjs/onerror 4.0.2-beta.2 → 4.0.2-beta.20
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/README.md +1 -1
- package/dist/app.d.ts +1 -1
- package/dist/app.js +2 -2
- package/dist/config/config.default.d.ts +4 -2
- package/dist/config/config.default.js +1 -3
- package/dist/lib/error_view.d.ts +5 -1
- package/dist/lib/error_view.js +42 -2
- package/dist/lib/onerror.d.ts +20 -0
- package/dist/lib/onerror.js +109 -0
- package/dist/lib/onerror_page.d.ts +5 -0
- package/dist/lib/{onerror_page.mustache.html → onerror_page.js} +84 -69
- package/dist/lib/utils.d.ts +1 -1
- package/package.json +24 -11
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Default error handling plugin for egg.
|
|
|
26
26
|
- `html: Function` - customize html error handler.
|
|
27
27
|
- `text: Function` - customize text error handler.
|
|
28
28
|
- `json: Function` - customize json error handler.
|
|
29
|
-
- `
|
|
29
|
+
- `js: Function` - customize JSONP error handler.
|
|
30
30
|
|
|
31
31
|
```ts
|
|
32
32
|
// config/config.default.ts
|
package/dist/app.d.ts
CHANGED
package/dist/app.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { accepts, detectErrorMessage, detectStatus, isProd } from "./lib/utils.js";
|
|
2
2
|
import { ErrorView } from "./lib/error_view.js";
|
|
3
|
+
import { onerror } from "./lib/onerror.js";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
import http from "node:http";
|
|
5
|
-
import { onerror } from "koa-onerror";
|
|
6
6
|
|
|
7
7
|
//#region src/app.ts
|
|
8
8
|
var Boot = class {
|
|
@@ -12,7 +12,7 @@ var Boot = class {
|
|
|
12
12
|
}
|
|
13
13
|
async didLoad() {
|
|
14
14
|
const config = this.app.config.onerror;
|
|
15
|
-
const viewTemplate = fs.readFileSync(config.templatePath, "utf8");
|
|
15
|
+
const viewTemplate = config.templatePath ? fs.readFileSync(config.templatePath, "utf8") : (await import("./lib/onerror_page.js")).ONERROR_PAGE_TEMPLATE;
|
|
16
16
|
const app = this.app;
|
|
17
17
|
app.on("error", (err, ctx) => {
|
|
18
18
|
if (!ctx) ctx = app.currentContext || app.createAnonymousContext();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OnerrorError, OnerrorOptions } from "
|
|
1
|
+
import { OnerrorError, OnerrorOptions } from "../lib/onerror.js";
|
|
2
2
|
import { Context } from "egg";
|
|
3
3
|
|
|
4
4
|
//#region src/config/config.default.d.ts
|
|
@@ -19,7 +19,9 @@ interface OnerrorConfig extends OnerrorOptions {
|
|
|
19
19
|
*/
|
|
20
20
|
appErrorFilter?: (err: OnerrorError, ctx: Context) => boolean;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Custom template path. If empty, uses the built-in error page template.
|
|
23
|
+
*
|
|
24
|
+
* Default: `''`
|
|
23
25
|
*/
|
|
24
26
|
templatePath: string;
|
|
25
27
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
|
|
3
1
|
//#region src/config/config.default.ts
|
|
4
2
|
var config_default_default = { onerror: {
|
|
5
3
|
errorPageUrl: "",
|
|
6
4
|
appErrorFilter: void 0,
|
|
7
|
-
templatePath:
|
|
5
|
+
templatePath: ""
|
|
8
6
|
} };
|
|
9
7
|
|
|
10
8
|
//#endregion
|
package/dist/lib/error_view.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OnerrorError } from "
|
|
1
|
+
import { OnerrorError } from "./onerror.js";
|
|
2
2
|
import { StackFrame } from "stack-trace";
|
|
3
3
|
import { Context } from "egg";
|
|
4
4
|
|
|
@@ -143,6 +143,10 @@ declare class ErrorView {
|
|
|
143
143
|
baseDir: string;
|
|
144
144
|
config: string;
|
|
145
145
|
};
|
|
146
|
+
serializeConfig(): unknown;
|
|
147
|
+
getConfigIgnoreList(): (string | RegExp)[];
|
|
148
|
+
redactConfig(value: unknown, ignoreList: (string | RegExp)[], ancestors?: WeakSet<object>): unknown;
|
|
149
|
+
shouldRedactConfigKey(key: string, ignoreList: (string | RegExp)[]): boolean;
|
|
146
150
|
}
|
|
147
151
|
//#endregion
|
|
148
152
|
export { ErrorView, Frame, FrameSource };
|
package/dist/lib/error_view.js
CHANGED
|
@@ -8,6 +8,18 @@ import stackTrace from "stack-trace";
|
|
|
8
8
|
|
|
9
9
|
//#region src/lib/error_view.ts
|
|
10
10
|
const startingSlashRegex = /\\|\//;
|
|
11
|
+
const defaultConfigIgnoreList = [
|
|
12
|
+
"pass",
|
|
13
|
+
"pwd",
|
|
14
|
+
"passd",
|
|
15
|
+
"passwd",
|
|
16
|
+
"password",
|
|
17
|
+
"keys",
|
|
18
|
+
"masterKey",
|
|
19
|
+
"accessKey",
|
|
20
|
+
/secret/i
|
|
21
|
+
];
|
|
22
|
+
const redactedValue = "<Redacted>";
|
|
11
23
|
var ErrorView = class {
|
|
12
24
|
ctx;
|
|
13
25
|
error;
|
|
@@ -211,13 +223,41 @@ var ErrorView = class {
|
|
|
211
223
|
* serialize app info object
|
|
212
224
|
*/
|
|
213
225
|
serializeAppInfo() {
|
|
214
|
-
|
|
215
|
-
if ("dumpConfigToObject" in this.app && typeof this.app.dumpConfigToObject === "function") config = this.app.dumpConfigToObject().config.config;
|
|
226
|
+
const config = this.serializeConfig();
|
|
216
227
|
return {
|
|
217
228
|
baseDir: this.app.config.baseDir,
|
|
218
229
|
config: util.inspect(config)
|
|
219
230
|
};
|
|
220
231
|
}
|
|
232
|
+
serializeConfig() {
|
|
233
|
+
if ("dumpConfigToObject" in this.app && typeof this.app.dumpConfigToObject === "function") return this.app.dumpConfigToObject().config.config;
|
|
234
|
+
return this.redactConfig(this.app.config, this.getConfigIgnoreList());
|
|
235
|
+
}
|
|
236
|
+
getConfigIgnoreList() {
|
|
237
|
+
try {
|
|
238
|
+
return Array.from(this.app.config.dump.ignore);
|
|
239
|
+
} catch {
|
|
240
|
+
return defaultConfigIgnoreList;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
redactConfig(value, ignoreList, ancestors = /* @__PURE__ */ new WeakSet()) {
|
|
244
|
+
if (!value || typeof value !== "object") return value;
|
|
245
|
+
if (value instanceof Date || value instanceof RegExp || value instanceof URL) return value.toString();
|
|
246
|
+
if (Buffer.isBuffer(value)) return value;
|
|
247
|
+
if (ancestors.has(value)) return "[Circular]";
|
|
248
|
+
ancestors.add(value);
|
|
249
|
+
try {
|
|
250
|
+
if (Array.isArray(value)) return value.map((item) => this.redactConfig(item, ignoreList, ancestors));
|
|
251
|
+
const result = {};
|
|
252
|
+
for (const key of Object.keys(value)) result[key] = this.shouldRedactConfigKey(key, ignoreList) ? redactedValue : this.redactConfig(value[key], ignoreList, ancestors);
|
|
253
|
+
return result;
|
|
254
|
+
} finally {
|
|
255
|
+
ancestors.delete(value);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
shouldRedactConfigKey(key, ignoreList) {
|
|
259
|
+
return ignoreList.some((item) => typeof item === "string" ? item === key : item.test(key));
|
|
260
|
+
}
|
|
221
261
|
};
|
|
222
262
|
|
|
223
263
|
//#endregion
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/lib/onerror.d.ts
|
|
2
|
+
type OnerrorError = Error & {
|
|
3
|
+
status: number;
|
|
4
|
+
code?: string;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
expose?: boolean;
|
|
7
|
+
};
|
|
8
|
+
type OnerrorHandler = (err: OnerrorError, ctx: any) => void;
|
|
9
|
+
interface OnerrorOptions {
|
|
10
|
+
text?: OnerrorHandler;
|
|
11
|
+
json?: OnerrorHandler;
|
|
12
|
+
html?: OnerrorHandler;
|
|
13
|
+
all?: OnerrorHandler;
|
|
14
|
+
js?: OnerrorHandler;
|
|
15
|
+
redirect?: string | null;
|
|
16
|
+
accepts?: (...args: string[]) => string;
|
|
17
|
+
}
|
|
18
|
+
declare function onerror(app: any, options?: OnerrorOptions): any;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { OnerrorError, OnerrorHandler, OnerrorOptions, onerror };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import { debuglog, inspect } from "node:util";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/onerror.ts
|
|
5
|
+
const debug = debuglog("egg-onerror");
|
|
6
|
+
const defaultOptions = {
|
|
7
|
+
text,
|
|
8
|
+
json,
|
|
9
|
+
html
|
|
10
|
+
};
|
|
11
|
+
function onerror(app, options) {
|
|
12
|
+
options = {
|
|
13
|
+
...defaultOptions,
|
|
14
|
+
...options
|
|
15
|
+
};
|
|
16
|
+
app.context.onerror = function(err) {
|
|
17
|
+
debug("onerror: %s", err);
|
|
18
|
+
if (err == null) return;
|
|
19
|
+
if (typeof this.req?.resume === "function") {
|
|
20
|
+
this.req.resume();
|
|
21
|
+
debug("resume the req stream");
|
|
22
|
+
}
|
|
23
|
+
if (!(err instanceof Error)) {
|
|
24
|
+
debug("err is not an instance of Error");
|
|
25
|
+
let errMsg = err;
|
|
26
|
+
if (typeof err === "object") try {
|
|
27
|
+
errMsg = JSON.stringify(err);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
debug("stringify error: %s", e);
|
|
30
|
+
errMsg = inspect(err);
|
|
31
|
+
}
|
|
32
|
+
const newError = /* @__PURE__ */ new Error("non-error thrown: " + errMsg);
|
|
33
|
+
if (err) {
|
|
34
|
+
if (err.name) newError.name = err.name;
|
|
35
|
+
if (err.message) newError.message = err.message;
|
|
36
|
+
if (err.stack) newError.stack = err.stack;
|
|
37
|
+
if (err.status) Reflect.set(newError, "status", err.status);
|
|
38
|
+
if (err.headers) Reflect.set(newError, "headers", err.headers);
|
|
39
|
+
}
|
|
40
|
+
err = newError;
|
|
41
|
+
debug("wrap err: %s", err);
|
|
42
|
+
}
|
|
43
|
+
const headerSent = this.headerSent || !this.writable;
|
|
44
|
+
if (headerSent) {
|
|
45
|
+
debug("headerSent is true");
|
|
46
|
+
err.headerSent = true;
|
|
47
|
+
}
|
|
48
|
+
this.app.emit("error", err, this);
|
|
49
|
+
if (headerSent) return;
|
|
50
|
+
if (err.code === "ENOENT") err.status = 404;
|
|
51
|
+
if (typeof err.status !== "number" || !http.STATUS_CODES[err.status]) err.status = 500;
|
|
52
|
+
this.status = err.status;
|
|
53
|
+
clearResponseHeaders(this);
|
|
54
|
+
if (err.headers) this.set(err.headers);
|
|
55
|
+
let type;
|
|
56
|
+
if (options.accepts) type = options.accepts.call(this, "html", "text", "json", "js");
|
|
57
|
+
else type = this.accepts("html", "text", "json", "js");
|
|
58
|
+
debug("accepts type: %s", type);
|
|
59
|
+
type = type || "text";
|
|
60
|
+
if (options.all) options.all.call(this, err, this);
|
|
61
|
+
else if (options.redirect && type !== "json") this.redirect(options.redirect);
|
|
62
|
+
else {
|
|
63
|
+
getHandler(options, type)?.call(this, err, this);
|
|
64
|
+
this.type = type;
|
|
65
|
+
}
|
|
66
|
+
if (type === "json" && typeof this.body !== "string") this.body = JSON.stringify(this.body);
|
|
67
|
+
debug("end the response, body: %s", this.body);
|
|
68
|
+
this.res.end(this.body);
|
|
69
|
+
};
|
|
70
|
+
return app;
|
|
71
|
+
}
|
|
72
|
+
function getHandler(options, type) {
|
|
73
|
+
if (type === "html" || type === "text" || type === "json" || type === "js") return options[type];
|
|
74
|
+
}
|
|
75
|
+
function isDev() {
|
|
76
|
+
return !process.env.NODE_ENV || process.env.NODE_ENV === "development";
|
|
77
|
+
}
|
|
78
|
+
function text(err, ctx) {
|
|
79
|
+
ctx.body = (isDev() || err.expose) && err.message ? err.message : http.STATUS_CODES[ctx.status];
|
|
80
|
+
}
|
|
81
|
+
function json(err, ctx) {
|
|
82
|
+
ctx.body = { error: (isDev() || err.expose) && err.message ? err.message : http.STATUS_CODES[ctx.status] };
|
|
83
|
+
}
|
|
84
|
+
function html(err, ctx) {
|
|
85
|
+
const message = (isDev() || err.expose) && err.message ? err.message : http.STATUS_CODES[ctx.status];
|
|
86
|
+
ctx.body = `<h2>${escapeHtml(String(err.status))} ${escapeHtml(String(message))}</h2>`;
|
|
87
|
+
ctx.type = "html";
|
|
88
|
+
}
|
|
89
|
+
function escapeHtml(value) {
|
|
90
|
+
return value.replace(/[&<>"']/g, (char) => {
|
|
91
|
+
switch (char) {
|
|
92
|
+
case "&": return "&";
|
|
93
|
+
case "<": return "<";
|
|
94
|
+
case ">": return ">";
|
|
95
|
+
case "\"": return """;
|
|
96
|
+
default: return "'";
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function clearResponseHeaders(ctx) {
|
|
101
|
+
const headers = ctx.response?.header ?? ctx.response?.headers ?? ctx.res.getHeaders?.() ?? {};
|
|
102
|
+
for (const name of Object.keys(headers)) {
|
|
103
|
+
if (name.toLowerCase() === "set-cookie") continue;
|
|
104
|
+
ctx.res.removeHeader(name);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
export { onerror };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
//#region src/lib/onerror_page.d.ts
|
|
2
|
+
/** Built-in error page template. */
|
|
3
|
+
declare const ONERROR_PAGE_TEMPLATE = "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title></title>\n <style>\n /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript&plugins=line-highlight+line-numbers+toolbar+show-language */\n /**\n * prism.js default theme for JavaScript, CSS and HTML\n * Based on dabblet (http://dabblet.com)\n * @author Lea Verou\n */\n code[class*='language-'],\n pre[class*='language-'] {\n color: black;\n background: none;\n text-shadow: 0 1px white;\n font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n text-align: left;\n white-space: pre;\n word-spacing: normal;\n word-break: normal;\n word-wrap: normal;\n line-height: 1.5;\n -moz-tab-size: 4;\n -o-tab-size: 4;\n tab-size: 4;\n -webkit-hyphens: none;\n -moz-hyphens: none;\n -ms-hyphens: none;\n hyphens: none;\n }\n pre[class*='language-']::-moz-selection,\n pre[class*='language-'] ::-moz-selection,\n code[class*='language-']::-moz-selection,\n code[class*='language-'] ::-moz-selection {\n text-shadow: none;\n background: #98d8b7;\n }\n pre[class*='language-']::selection,\n pre[class*='language-'] ::selection,\n code[class*='language-']::selection,\n code[class*='language-'] ::selection {\n text-shadow: none;\n background: #98d8b7;\n }\n @media print {\n code[class*='language-'],\n pre[class*='language-'] {\n text-shadow: none;\n }\n }\n /* Code blocks */\n pre[class*='language-'] {\n padding: 1em;\n margin: 0.5em 0;\n overflow: auto;\n }\n :not(pre) > code[class*='language-'],\n pre[class*='language-'] {\n background: #f5f2f0;\n }\n /* Inline code */\n :not(pre) > code[class*='language-'] {\n padding: 0.1em;\n border-radius: 0.3em;\n white-space: normal;\n }\n .token.comment,\n .token.prolog,\n .token.doctype,\n .token.cdata {\n color: slategray;\n }\n .token.punctuation {\n color: #999;\n }\n .namespace {\n opacity: 0.7;\n }\n .token.property,\n .token.tag,\n .token.boolean,\n .token.number,\n .token.constant,\n .token.symbol,\n .token.deleted {\n color: #905;\n }\n .token.selector,\n .token.attr-name,\n .token.string,\n .token.char,\n .token.builtin,\n .token.inserted {\n color: #690;\n }\n .token.operator,\n .token.entity,\n .token.url,\n .language-css .token.string,\n .style .token.string {\n color: #a67f59;\n background: hsla(0, 0%, 100%, 0.5);\n }\n .token.atrule,\n .token.attr-value,\n .token.keyword {\n color: #07a;\n }\n .token.function {\n color: #dd4a68;\n }\n .token.regex,\n .token.important,\n .token.variable {\n color: #e90;\n }\n .token.important,\n .token.bold {\n font-weight: bold;\n }\n .token.italic {\n font-style: italic;\n }\n .token.entity {\n cursor: help;\n }\n pre[data-line] {\n position: relative;\n padding: 1em 0 1em 3em;\n }\n .line-highlight {\n position: absolute;\n left: 0;\n right: 0;\n padding: inherit 0;\n margin-top: 1em; /* Same as .prism’s padding-top */\n background: hsla(24, 20%, 50%, 0.08);\n background: linear-gradient(to right, hsla(24, 20%, 50%, 0.1) 70%, hsla(24, 20%, 50%, 0));\n pointer-events: none;\n line-height: inherit;\n white-space: pre;\n }\n .line-highlight:before,\n .line-highlight[data-end]:after {\n content: attr(data-start);\n position: absolute;\n top: 0.4em;\n left: 0.6em;\n min-width: 1em;\n padding: 0 0.5em;\n background-color: hsla(24, 20%, 50%, 0.4);\n color: hsl(24, 20%, 95%);\n font: bold 65%/1.5 sans-serif;\n text-align: center;\n vertical-align: 0.3em;\n border-radius: 999px;\n text-shadow: none;\n box-shadow: 0 1px white;\n }\n .line-highlight[data-end]:after {\n content: attr(data-end);\n top: auto;\n bottom: 0.4em;\n }\n pre.line-numbers {\n position: relative;\n padding-left: 3.8em;\n counter-reset: linenumber;\n }\n pre.line-numbers > code {\n position: relative;\n }\n .line-numbers .line-numbers-rows {\n position: absolute;\n pointer-events: none;\n top: 0;\n font-size: 100%;\n left: -3.8em;\n width: 3em; /* works for line-numbers below 1000 lines */\n letter-spacing: -1px;\n border-right: 1px solid #999;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n }\n .line-numbers-rows > span {\n pointer-events: none;\n display: block;\n counter-increment: linenumber;\n }\n .line-numbers-rows > span:before {\n content: counter(linenumber);\n color: #999;\n display: block;\n padding-right: 0.8em;\n text-align: right;\n }\n pre.code-toolbar {\n position: relative;\n }\n pre.code-toolbar > .toolbar {\n position: absolute;\n top: 0.3em;\n right: 0.2em;\n transition: opacity 0.3s ease-in-out;\n opacity: 0;\n }\n pre.code-toolbar:hover > .toolbar {\n opacity: 1;\n }\n pre.code-toolbar > .toolbar .toolbar-item {\n display: inline-block;\n }\n pre.code-toolbar > .toolbar a {\n cursor: pointer;\n }\n pre.code-toolbar > .toolbar button {\n background: none;\n border: 0;\n color: inherit;\n font: inherit;\n line-height: normal;\n overflow: visible;\n padding: 0;\n -webkit-user-select: none; /* for button */\n -moz-user-select: none;\n -ms-user-select: none;\n }\n pre.code-toolbar > .toolbar a,\n pre.code-toolbar > .toolbar button,\n pre.code-toolbar > .toolbar span {\n color: #bbb;\n font-size: 0.8em;\n padding: 0 0.5em;\n background: #f5f2f0;\n background: rgba(224, 224, 224, 0.2);\n box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2);\n border-radius: 0.5em;\n }\n pre.code-toolbar > .toolbar a:hover,\n pre.code-toolbar > .toolbar a:focus,\n pre.code-toolbar > .toolbar button:hover,\n pre.code-toolbar > .toolbar button:focus,\n pre.code-toolbar > .toolbar span:hover,\n pre.code-toolbar > .toolbar span:focus {\n color: inherit;\n text-decoration: none;\n }\n </style>\n\n <style>\n @keyframes hover-color {\n from {\n border-color: #c0c0c0;\n }\n to {\n border-color: #53b783;\n }\n }\n .magic-radio,\n .magic-checkbox {\n position: absolute;\n display: none;\n }\n .magic-radio[disabled],\n .magic-checkbox[disabled] {\n cursor: not-allowed;\n }\n .magic-radio + label,\n .magic-checkbox + label {\n position: relative;\n display: block;\n padding-left: 30px;\n cursor: pointer;\n vertical-align: middle;\n }\n .magic-radio + label:hover:before,\n .magic-checkbox + label:hover:before {\n animation-duration: 0.4s;\n animation-fill-mode: both;\n animation-name: hover-color;\n }\n .magic-radio + label:before,\n .magic-checkbox + label:before {\n position: absolute;\n top: 0;\n left: 0;\n display: inline-block;\n width: 20px;\n height: 20px;\n content: '';\n border: 1px solid #c0c0c0;\n }\n .magic-radio + label:after,\n .magic-checkbox + label:after {\n position: absolute;\n display: none;\n content: '';\n }\n .magic-radio[disabled] + label,\n .magic-checkbox[disabled] + label {\n cursor: not-allowed;\n color: #e4e4e4;\n }\n .magic-radio[disabled] + label:hover,\n .magic-radio[disabled] + label:before,\n .magic-radio[disabled] + label:after,\n .magic-checkbox[disabled] + label:hover,\n .magic-checkbox[disabled] + label:before,\n .magic-checkbox[disabled] + label:after {\n cursor: not-allowed;\n }\n .magic-radio[disabled] + label:hover:before,\n .magic-checkbox[disabled] + label:hover:before {\n border: 1px solid #e4e4e4;\n animation-name: none;\n }\n .magic-radio[disabled] + label:before,\n .magic-checkbox[disabled] + label:before {\n border-color: #e4e4e4;\n }\n .magic-radio:checked + label:before,\n .magic-checkbox:checked + label:before {\n animation-name: none;\n }\n .magic-radio:checked + label:after,\n .magic-checkbox:checked + label:after {\n display: block;\n }\n .magic-radio + label:before {\n border-radius: 50%;\n }\n .magic-radio + label:after {\n top: 6px;\n left: 6px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #53b783;\n }\n .magic-radio:checked + label:before {\n border: 1px solid #53b783;\n }\n .magic-radio:checked[disabled] + label:before {\n border: 1px solid #c9e2f9;\n }\n .magic-radio:checked[disabled] + label:after {\n background: #c9e2f9;\n }\n .magic-checkbox + label:before {\n border-radius: 3px;\n }\n .magic-checkbox + label:after {\n top: 2px;\n left: 7px;\n box-sizing: border-box;\n width: 6px;\n height: 12px;\n transform: rotate(45deg);\n border-width: 2px;\n border-style: solid;\n border-color: #fff;\n border-top: 0;\n border-left: 0;\n }\n .magic-checkbox:checked + label:before {\n border: #53b783;\n background: #53b783;\n }\n .magic-checkbox:checked[disabled] + label:before {\n border: #c9e2f9;\n background: #c9e2f9;\n }\n </style>\n\n <style>\n html,\n body {\n height: 100%;\n width: 100%;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n body {\n font-family:\n Helvetica Neue For Number,\n -apple-system,\n BlinkMacSystemFont,\n Segoe UI,\n Roboto,\n PingFang SC,\n Hiragino Sans GB,\n Microsoft YaHei,\n Helvetica Neue,\n Helvetica,\n Arial,\n sans-serif;\n font-size: 14px;\n line-height: 24px;\n color: #444;\n }\n * {\n padding: 0;\n margin: 0;\n }\n ::selection {\n text-shadow: none;\n color: #fff;\n background: #98d8b7;\n }\n ::-moz-selection {\n text-shadow: none;\n color: #fff;\n background: #98d8b7;\n }\n .error-page {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n .error-logo {\n position: absolute;\n top: -15px;\n right: 0px;\n }\n .error-stack {\n background: #f1f1f1;\n padding: 140px 80px 40px;\n box-sizing: border-box;\n border-bottom: 1px solid #e2e2e2;\n }\n .error-status {\n color: #afafaf;\n font-size: 150px;\n position: absolute;\n opacity: 0.2;\n left: 76px;\n top: 80px;\n font-weight: 600;\n margin-bottom: 10px;\n }\n .error-name {\n color: #db5461;\n font-size: 18px;\n font-family: menlo, 'sans-serif';\n font-weight: 300;\n margin-bottom: 15px;\n }\n .error-title {\n border-bottom: 1px solid #e0e0e0;\n padding-bottom: 26px;\n margin-bottom: 20px;\n margin-top: 48px;\n }\n .error-title .box {\n color: #db5461;\n font-weight: 700;\n font-size: 20px;\n margin-left: 5px;\n }\n .error-title .context {\n color: #db5461;\n font-weight: 400;\n margin-left: 5px;\n margin-top: 48px;\n line-height: 1.5;\n }\n .error-frames {\n display: flex;\n flex-direction: row-reverse;\n margin-top: 40px;\n }\n .frame-preview {\n background: #fff;\n width: 50%;\n box-shadow: 0px 0px 9px #d3d3d3;\n height: 100%;\n box-sizing: border-box;\n overflow: auto;\n }\n .frame-stack {\n margin-right: 40px;\n flex: 1;\n padding: 10px 0;\n box-sizing: border-box;\n }\n .frames-list {\n overflow: auto;\n max-height: 334px;\n }\n .frames-filter-selector {\n margin-bottom: 30px;\n margin-left: 8px;\n }\n .request-details {\n padding: 50px 80px;\n }\n .request-title {\n text-transform: uppercase;\n font-size: 18px;\n letter-spacing: 1px;\n padding: 0 5px 5px 5px;\n margin-bottom: 15px;\n color: #53b783;\n }\n .request-details .table {\n width: 100%;\n border-collapse: collapse;\n margin-bottom: 80px;\n }\n .request-details .tr {\n display: flex;\n flex-direction: row;\n }\n .request-details .tr:nth-of-type(even) {\n background: #fbfbfb;\n }\n .request-details .table .td {\n padding: 6px 5px;\n font-size: 14px;\n letter-spacing: 0.4px;\n color: #455275;\n border-bottom: 1px solid #e8e8e8;\n word-break: break-word;\n }\n .request-details .table .td.title {\n flex: 1;\n color: #565655;\n font-size: 14px;\n font-weight: 600;\n }\n .request-details .table .td.content {\n width: 70%;\n }\n .request-details .table .td.content.code {\n background: #fff;\n width: 70%;\n box-shadow: 0px 0px 9px #d3d3d3;\n height: 100%;\n box-sizing: border-box;\n overflow: auto;\n }\n code[class*='language-'],\n pre[class*='language-'] {\n background: transparent;\n font-size: 13px;\n line-height: 1.8;\n }\n .line-numbers .line-numbers-rows {\n border: none;\n }\n .frame-row {\n display: flex;\n justify-content: space-between;\n padding: 6px 10px 6px 34px;\n position: relative;\n cursor: pointer;\n transition: background 300ms ease;\n }\n .frame-row.native-frame {\n display: none;\n opacity: 0.4;\n }\n .frame-row.native-frame.force-show {\n display: flex;\n }\n .frame-row:after {\n content: '';\n background: #db5461;\n position: absolute;\n top: 50%;\n left: 10px;\n transform: translateY(-50%);\n height: 10px;\n width: 10px;\n border-radius: 24px;\n }\n .frame-row:hover,\n .frame-row.active {\n background: #fff;\n }\n .frame-row.active {\n opacity: 1;\n }\n .frame-row-filepath {\n color: #455275;\n font-weight: 600;\n margin-right: 15px;\n }\n .frame-context {\n display: none;\n }\n .frame-row-code {\n color: #999;\n }\n #frame-file {\n color: #455275;\n font-weight: 600;\n border-bottom: 1px solid #e8e8e8;\n padding: 10px 22px;\n }\n #frame-method {\n color: #999;\n font-weight: 400;\n border-top: 1px solid #e8e8e8;\n padding: 10px 22px;\n }\n .is-hidden {\n display: none;\n }\n </style>\n </head>\n <body>\n <section class=\"error-page\">\n <section class=\"error-stack\">\n <h3 class=\"error-status\">{{ status }}</h3>\n <div class=\"error-title\">\n <h1 class=\"box\">{{ name }} in {{ request.url }}</h1>\n <div class=\"context\">{{ message }}</div>\n </div>\n\n <img class=\"error-logo\" src=\"https://zos.alipayobjects.com/rmsportal/JFKAMfmPehWfhBPdCjrw.svg\" />\n\n <div class=\"error-frames\">\n <div class=\"frame-preview is-hidden\">\n <div id=\"frame-file\"></div>\n <div id=\"frame-code\">\n <pre class=\"line-numbers\"><code id=\"code-drop\"></code></pre>\n </div>\n <div id=\"frame-method\"></div>\n </div>\n\n <div class=\"frame-stack\">\n <div class=\"frames-filter-selector\">\n <input type=\"checkbox\" class=\"magic-checkbox\" name=\"frames-filter\" id=\"frames-filter\" />\n <label for=\"frames-filter\">Show all frames</label>\n </div>\n\n <div class=\"frames-list\">\n {{#frames}} {{index}}\n <div class=\"frame-row {{classes}}\">\n <div class=\"frame-row-filepath\">{{ file }}:{{ line }}:{{ column }}</div>\n <div class=\"frame-row-code\">{{ method }}</div>\n <div\n class=\"frame-context\"\n data-start=\"{{context.start}}\"\n data-line=\"{{line}}\"\n data-file=\"{{file}}\"\n data-method=\"{{method}}\"\n data-extname=\"{{extname}}\"\n data-line-column=\"{{line}}:{{column}}\"\n >\n {{ context.pre }} {{ context.line }} {{ context.post }}\n </div>\n </div>\n {{/frames}}\n </div>\n </div>\n </div>\n </section>\n\n <section class=\"request-details\">\n <h2 class=\"request-title\">Request Details</h2>\n <div class=\"table\">\n <div class=\"tr\">\n <div class=\"td title\">URI</div>\n <div class=\"td content\">{{ request.url }}</div>\n </div>\n\n <div class=\"tr\">\n <div class=\"td title\">Request Method</div>\n <div class=\"td content\">{{ request.method }}</div>\n </div>\n\n <div class=\"tr\">\n <div class=\"td title\">HTTP Version</div>\n <div class=\"td content\">{{ request.httpVersion }}</div>\n </div>\n\n <div class=\"tr\">\n <div class=\"td title\">Connection</div>\n <div class=\"td content\">{{ request.connection }}</div>\n </div>\n </div>\n\n <h2 class=\"request-title\">Headers</h2>\n <div class=\"table\">\n {{#request.headers}}\n <div class=\"tr\">\n <div class=\"td title\">{{ key }}</div>\n <div class=\"td content\">{{ value }}</div>\n </div>\n {{/request.headers}}\n </div>\n\n <h2 class=\"request-title\">Cookies</h2>\n <div class=\"table\">\n {{#request.cookies}}\n <div class=\"tr\">\n <div class=\"td title\">{{ key }}</div>\n <div class=\"td content\">{{ value }}</div>\n </div>\n {{/request.cookies}}\n </div>\n <h2 class=\"request-title\">AppInfo</h2>\n <div class=\"table\">\n <div class=\"tr\">\n <div class=\"td title\">baseDir</div>\n <div class=\"td content\">{{ appInfo.baseDir }}</div>\n </div>\n <div class=\"tr\">\n <div class=\"td title\">config</div>\n <div class=\"td content code\">\n <pre class=\"line-numbers\"><code class=\"language-json\">{{ appInfo.config }}</code></pre>\n </div>\n </div>\n </div>\n </section>\n\n <script type=\"text/javascript\">\n var _self =\n 'undefined' != typeof window\n ? window\n : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope\n ? self\n : {},\n Prism = (function () {\n var e = /\\blang(?:uage)?-(\\w+)\\b/i,\n t = 0,\n n = (_self.Prism = {\n util: {\n encode: function (e) {\n return e instanceof a\n ? new a(e.type, n.util.encode(e.content), e.alias)\n : 'Array' === n.util.type(e)\n ? e.map(n.util.encode)\n : e\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/\\u00a0/g, ' ');\n },\n type: function (e) {\n return Object.prototype.toString.call(e).match(/\\[object (\\w+)\\]/)[1];\n },\n objId: function (e) {\n return (e.__id || Object.defineProperty(e, '__id', { value: ++t }), e.__id);\n },\n clone: function (e) {\n var t = n.util.type(e);\n switch (t) {\n case 'Object':\n var a = {};\n for (var r in e) e.hasOwnProperty(r) && (a[r] = n.util.clone(e[r]));\n return a;\n case 'Array':\n return (\n e.map &&\n e.map(function (e) {\n return n.util.clone(e);\n })\n );\n }\n return e;\n },\n },\n languages: {\n extend: function (e, t) {\n var a = n.util.clone(n.languages[e]);\n for (var r in t) a[r] = t[r];\n return a;\n },\n insertBefore: function (e, t, a, r) {\n r = r || n.languages;\n var i = r[e];\n if (2 == arguments.length) {\n a = arguments[1];\n for (var l in a) a.hasOwnProperty(l) && (i[l] = a[l]);\n return i;\n }\n var o = {};\n for (var s in i)\n if (i.hasOwnProperty(s)) {\n if (s == t) for (var l in a) a.hasOwnProperty(l) && (o[l] = a[l]);\n o[s] = i[s];\n }\n return (\n n.languages.DFS(n.languages, function (t, n) {\n n === r[e] && t != e && (this[t] = o);\n }),\n (r[e] = o)\n );\n },\n DFS: function (e, t, a, r) {\n r = r || {};\n for (var i in e)\n e.hasOwnProperty(i) &&\n (t.call(e, i, e[i], a || i),\n 'Object' !== n.util.type(e[i]) || r[n.util.objId(e[i])]\n ? 'Array' !== n.util.type(e[i]) ||\n r[n.util.objId(e[i])] ||\n ((r[n.util.objId(e[i])] = !0), n.languages.DFS(e[i], t, i, r))\n : ((r[n.util.objId(e[i])] = !0), n.languages.DFS(e[i], t, null, r)));\n },\n },\n plugins: {},\n highlightAll: function (e, t) {\n var a = {\n callback: t,\n selector:\n 'code[class*=\"language-\"], [class*=\"language-\"] code, code[class*=\"lang-\"], [class*=\"lang-\"] code',\n };\n n.hooks.run('before-highlightall', a);\n for (var r, i = a.elements || document.querySelectorAll(a.selector), l = 0; (r = i[l++]); )\n n.highlightElement(r, e === !0, a.callback);\n },\n highlightElement: function (t, a, r) {\n for (var i, l, o = t; o && !e.test(o.className); ) o = o.parentNode;\n (o && ((i = (o.className.match(e) || [, ''])[1].toLowerCase()), (l = n.languages[i])),\n (t.className = t.className.replace(e, '').replace(/\\s+/g, ' ') + ' language-' + i),\n (o = t.parentNode),\n /pre/i.test(o.nodeName) &&\n (o.className = o.className.replace(e, '').replace(/\\s+/g, ' ') + ' language-' + i));\n var s = t.textContent,\n u = { element: t, language: i, grammar: l, code: s };\n if ((n.hooks.run('before-sanity-check', u), !u.code || !u.grammar))\n return (u.code && (u.element.textContent = u.code), n.hooks.run('complete', u), void 0);\n if ((n.hooks.run('before-highlight', u), a && _self.Worker)) {\n var g = new Worker(n.filename);\n ((g.onmessage = function (e) {\n ((u.highlightedCode = e.data),\n n.hooks.run('before-insert', u),\n (u.element.innerHTML = u.highlightedCode),\n r && r.call(u.element),\n n.hooks.run('after-highlight', u),\n n.hooks.run('complete', u));\n }),\n g.postMessage(JSON.stringify({ language: u.language, code: u.code, immediateClose: !0 })));\n } else\n ((u.highlightedCode = n.highlight(u.code, u.grammar, u.language)),\n n.hooks.run('before-insert', u),\n (u.element.innerHTML = u.highlightedCode),\n r && r.call(t),\n n.hooks.run('after-highlight', u),\n n.hooks.run('complete', u));\n },\n highlight: function (e, t, r) {\n var i = n.tokenize(e, t);\n return a.stringify(n.util.encode(i), r);\n },\n tokenize: function (e, t) {\n var a = n.Token,\n r = [e],\n i = t.rest;\n if (i) {\n for (var l in i) t[l] = i[l];\n delete t.rest;\n }\n e: for (var l in t)\n if (t.hasOwnProperty(l) && t[l]) {\n var o = t[l];\n o = 'Array' === n.util.type(o) ? o : [o];\n for (var s = 0; s < o.length; ++s) {\n var u = o[s],\n g = u.inside,\n c = !!u.lookbehind,\n h = !!u.greedy,\n f = 0,\n d = u.alias;\n if (h && !u.pattern.global) {\n var p = u.pattern.toString().match(/[imuy]*$/)[0];\n u.pattern = RegExp(u.pattern.source, p + 'g');\n }\n u = u.pattern || u;\n for (var m = 0, y = 0; m < r.length; y += r[m].length, ++m) {\n var v = r[m];\n if (r.length > e.length) break e;\n if (!(v instanceof a)) {\n u.lastIndex = 0;\n var b = u.exec(v),\n k = 1;\n if (!b && h && m != r.length - 1) {\n if (((u.lastIndex = y), (b = u.exec(e)), !b)) break;\n for (\n var w = b.index + (c ? b[1].length : 0),\n _ = b.index + b[0].length,\n A = m,\n P = y,\n j = r.length;\n j > A && _ > P;\n ++A\n )\n ((P += r[A].length), w >= P && (++m, (y = P)));\n if (r[m] instanceof a || r[A - 1].greedy) continue;\n ((k = A - m), (v = e.slice(y, P)), (b.index -= y));\n }\n if (b) {\n c && (f = b[1].length);\n var w = b.index + f,\n b = b[0].slice(f),\n _ = w + b.length,\n x = v.slice(0, w),\n O = v.slice(_),\n S = [m, k];\n x && S.push(x);\n var N = new a(l, g ? n.tokenize(b, g) : b, d, b, h);\n (S.push(N), O && S.push(O), Array.prototype.splice.apply(r, S));\n }\n }\n }\n }\n }\n return r;\n },\n hooks: {\n all: {},\n add: function (e, t) {\n var a = n.hooks.all;\n ((a[e] = a[e] || []), a[e].push(t));\n },\n run: function (e, t) {\n var a = n.hooks.all[e];\n if (a && a.length) for (var r, i = 0; (r = a[i++]); ) r(t);\n },\n },\n }),\n a = (n.Token = function (e, t, n, a, r) {\n ((this.type = e),\n (this.content = t),\n (this.alias = n),\n (this.length = 0 | (a || '').length),\n (this.greedy = !!r));\n });\n if (\n ((a.stringify = function (e, t, r) {\n if ('string' == typeof e) return e;\n if ('Array' === n.util.type(e))\n return e\n .map(function (n) {\n return a.stringify(n, t, e);\n })\n .join('');\n var i = {\n type: e.type,\n content: a.stringify(e.content, t, r),\n tag: 'span',\n classes: ['token', e.type],\n attributes: {},\n language: t,\n parent: r,\n };\n if (('comment' == i.type && (i.attributes.spellcheck = 'true'), e.alias)) {\n var l = 'Array' === n.util.type(e.alias) ? e.alias : [e.alias];\n Array.prototype.push.apply(i.classes, l);\n }\n n.hooks.run('wrap', i);\n var o = Object.keys(i.attributes)\n .map(function (e) {\n return e + '=\"' + (i.attributes[e] || '').replace(/\"/g, '"') + '\"';\n })\n .join(' ');\n return (\n '<' +\n i.tag +\n ' class=\"' +\n i.classes.join(' ') +\n '\"' +\n (o ? ' ' + o : '') +\n '>' +\n i.content +\n '</' +\n i.tag +\n '>'\n );\n }),\n !_self.document)\n )\n return _self.addEventListener\n ? (_self.addEventListener(\n 'message',\n function (e) {\n var t = JSON.parse(e.data),\n a = t.language,\n r = t.code,\n i = t.immediateClose;\n (_self.postMessage(n.highlight(r, n.languages[a], a)), i && _self.close());\n },\n !1\n ),\n _self.Prism)\n : _self.Prism;\n var r = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop();\n return (\n r &&\n ((n.filename = r.src),\n document.addEventListener &&\n !r.hasAttribute('data-manual') &&\n ('loading' !== document.readyState\n ? window.requestAnimationFrame\n ? window.requestAnimationFrame(n.highlightAll)\n : window.setTimeout(n.highlightAll, 16)\n : document.addEventListener('DOMContentLoaded', n.highlightAll))),\n _self.Prism\n );\n })();\n ('undefined' != typeof module && module.exports && (module.exports = Prism),\n 'undefined' != typeof global && (global.Prism = Prism));\n ((Prism.languages.markup = {\n comment: /<!--[\\w\\W]*?-->/,\n prolog: /<\\?[\\w\\W]+?\\?>/,\n doctype: /<!DOCTYPE[\\w\\W]+?>/i,\n cdata: /<!\\[CDATA\\[[\\w\\W]*?]]>/i,\n tag: {\n pattern:\n /<\\/?(?!\\d)[^\\s>\\/=$<]+(?:\\s+[^\\s>\\/=]+(?:=(?:(\"|')(?:\\\\\\1|\\\\?(?!\\1)[\\w\\W])*\\1|[^\\s'\">=]+))?)*\\s*\\/?>/i,\n inside: {\n tag: { pattern: /^<\\/?[^\\s>\\/]+/i, inside: { punctuation: /^<\\/?/, namespace: /^[^\\s>\\/:]+:/ } },\n 'attr-value': { pattern: /=(?:('|\")[\\w\\W]*?(\\1)|[^\\s>]+)/i, inside: { punctuation: /[=>\"']/ } },\n punctuation: /\\/?>/,\n 'attr-name': { pattern: /[^\\s>\\/]+/, inside: { namespace: /^[^\\s>\\/:]+:/ } },\n },\n },\n entity: /&#?[\\da-z]{1,8};/i,\n }),\n Prism.hooks.add('wrap', function (a) {\n 'entity' === a.type && (a.attributes.title = a.content.replace(/&/, '&'));\n }),\n (Prism.languages.xml = Prism.languages.markup),\n (Prism.languages.html = Prism.languages.markup),\n (Prism.languages.mathml = Prism.languages.markup),\n (Prism.languages.svg = Prism.languages.markup));\n ((Prism.languages.css = {\n comment: /\\/\\*[\\w\\W]*?\\*\\//,\n atrule: { pattern: /@[\\w-]+?.*?(;|(?=\\s*\\{))/i, inside: { rule: /@[\\w-]+/ } },\n url: /url\\((?:([\"'])(\\\\(?:\\r\\n|[\\w\\W])|(?!\\1)[^\\\\\\r\\n])*\\1|.*?)\\)/i,\n selector: /[^\\{\\}\\s][^\\{\\};]*?(?=\\s*\\{)/,\n string: { pattern: /(\"|')(\\\\(?:\\r\\n|[\\w\\W])|(?!\\1)[^\\\\\\r\\n])*\\1/, greedy: !0 },\n property: /(\\b|\\B)[\\w-]+(?=\\s*:)/i,\n important: /\\B!important\\b/i,\n function: /[-a-z0-9]+(?=\\()/i,\n punctuation: /[(){};:]/,\n }),\n (Prism.languages.css.atrule.inside.rest = Prism.util.clone(Prism.languages.css)),\n Prism.languages.markup &&\n (Prism.languages.insertBefore('markup', 'tag', {\n style: {\n pattern: /(<style[\\w\\W]*?>)[\\w\\W]*?(?=<\\/style>)/i,\n lookbehind: !0,\n inside: Prism.languages.css,\n alias: 'language-css',\n },\n }),\n Prism.languages.insertBefore(\n 'inside',\n 'attr-value',\n {\n 'style-attr': {\n pattern: /\\s*style=(\"|').*?\\1/i,\n inside: {\n 'attr-name': { pattern: /^\\s*style/i, inside: Prism.languages.markup.tag.inside },\n punctuation: /^\\s*=\\s*['\"]|['\"]\\s*$/,\n 'attr-value': { pattern: /.+/i, inside: Prism.languages.css },\n },\n alias: 'language-css',\n },\n },\n Prism.languages.markup.tag\n )));\n Prism.languages.clike = {\n comment: [\n { pattern: /(^|[^\\\\])\\/\\*[\\w\\W]*?\\*\\//, lookbehind: !0 },\n { pattern: /(^|[^\\\\:])\\/\\/.*/, lookbehind: !0 },\n ],\n string: { pattern: /([\"'])(\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1/, greedy: !0 },\n 'class-name': {\n pattern:\n /((?:\\b(?:class|interface|extends|implements|trait|instanceof|new)\\s+)|(?:catch\\s+\\())[a-z0-9_\\.\\\\]+/i,\n lookbehind: !0,\n inside: { punctuation: /(\\.|\\\\)/ },\n },\n keyword:\n /\\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\\b/,\n boolean: /\\b(true|false)\\b/,\n function: /[a-z0-9_]+(?=\\()/i,\n number: /\\b-?(?:0x[\\da-f]+|\\d*\\.?\\d+(?:e[+-]?\\d+)?)\\b/i,\n operator: /--?|\\+\\+?|!=?=?|<=?|>=?|==?=?|&&?|\\|\\|?|\\?|\\*|\\/|~|\\^|%/,\n punctuation: /[{}[\\];(),.:]/,\n };\n ((Prism.languages.javascript = Prism.languages.extend('clike', {\n keyword:\n /\\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\\b/,\n number: /\\b-?(0x[\\dA-Fa-f]+|0b[01]+|0o[0-7]+|\\d*\\.?\\d+([Ee][+-]?\\d+)?|NaN|Infinity)\\b/,\n function: /[_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*(?=\\()/i,\n operator: /--?|\\+\\+?|!=?=?|<=?|>=?|==?=?|&&?|\\|\\|?|\\?|\\*\\*?|\\/|~|\\^|%|\\.{3}/,\n })),\n Prism.languages.insertBefore('javascript', 'keyword', {\n regex: {\n pattern: /(^|[^\\/])\\/(?!\\/)(\\[.+?]|\\\\.|[^\\/\\\\\\r\\n])+\\/[gimyu]{0,5}(?=\\s*($|[\\r\\n,.;})]))/,\n lookbehind: !0,\n greedy: !0,\n },\n }),\n Prism.languages.insertBefore('javascript', 'string', {\n 'template-string': {\n pattern: /`(?:\\\\\\\\|\\\\?[^\\\\])*?`/,\n greedy: !0,\n inside: {\n interpolation: {\n pattern: /\\$\\{[^}]+\\}/,\n inside: {\n 'interpolation-punctuation': { pattern: /^\\$\\{|\\}$/, alias: 'punctuation' },\n rest: Prism.languages.javascript,\n },\n },\n string: /[\\s\\S]+/,\n },\n },\n }),\n Prism.languages.markup &&\n Prism.languages.insertBefore('markup', 'tag', {\n script: {\n pattern: /(<script[\\w\\W]*?>)[\\w\\W]*?(?=<\\/script>)/i,\n lookbehind: !0,\n inside: Prism.languages.javascript,\n alias: 'language-javascript',\n },\n }),\n (Prism.languages.js = Prism.languages.javascript));\n ((Prism.languages.json = {\n property: /\"(?:\\\\.|[^\\\\\"])*\"(?=\\s*:)/gi,\n string: /\"(?!:)(?:\\\\.|[^\\\\\"])*\"(?!:)/g,\n number: /\\b-?(0x[\\dA-Fa-f]+|\\d*\\.?\\d+([Ee][+-]?\\d+)?)\\b/g,\n punctuation: /[{}[\\]);,]/g,\n operator: /:/g,\n boolean: /\\b(true|false)\\b/gi,\n null: /\\bnull\\b/gi,\n }),\n (Prism.languages.jsonp = Prism.languages.json));\n ((Prism.languages.typescript = Prism.languages.extend('javascript', {\n keyword:\n /\\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield|false|true|module|declare|constructor|string|Function|any|number|boolean|Array|enum|symbol|namespace|abstract|require|type)\\b/,\n })),\n (Prism.languages.ts = Prism.languages.typescript));\n !(function () {\n function e(e, t) {\n return Array.prototype.slice.call((t || document).querySelectorAll(e));\n }\n function t(e, t) {\n return ((t = ' ' + t + ' '), (' ' + e.className + ' ').replace(/[\\n\\t]/g, ' ').indexOf(t) > -1);\n }\n function n(e, n, i) {\n for (\n var o,\n a = n.replace(/\\s+/g, '').split(','),\n l = +e.getAttribute('data-line-offset') || 0,\n d = r() ? parseInt : parseFloat,\n c = d(getComputedStyle(e).lineHeight),\n s = 0;\n (o = a[s++]);\n\n ) {\n o = o.split('-');\n var u = +o[0],\n m = +o[1] || u,\n h = document.createElement('div');\n ((h.textContent = Array(m - u + 2).join('\\n')),\n h.setAttribute('aria-hidden', 'true'),\n (h.className = (i || '') + ' line-highlight'),\n t(e, 'line-numbers') || (h.setAttribute('data-start', u), m > u && h.setAttribute('data-end', m)),\n (h.style.top = (u - l - 1) * c + 'px'),\n t(e, 'line-numbers') ? e.appendChild(h) : (e.querySelector('code') || e).appendChild(h));\n }\n }\n function i() {\n var t = location.hash.slice(1);\n e('.temporary.line-highlight').forEach(function (e) {\n e.parentNode.removeChild(e);\n });\n var i = (t.match(/\\.([\\d,-]+)$/) || [, ''])[1];\n if (i && !document.getElementById(t)) {\n var r = t.slice(0, t.lastIndexOf('.')),\n o = document.getElementById(r);\n o &&\n (o.hasAttribute('data-line') || o.setAttribute('data-line', ''),\n n(o, i, 'temporary '),\n document.querySelector('.temporary.line-highlight').scrollIntoView());\n }\n }\n if ('undefined' != typeof self && self.Prism && self.document && document.querySelector) {\n var r = (function () {\n var e;\n return function () {\n if ('undefined' == typeof e) {\n var t = document.createElement('div');\n ((t.style.fontSize = '13px'),\n (t.style.lineHeight = '1.5'),\n (t.style.padding = 0),\n (t.style.border = 0),\n (t.innerHTML = ' <br /> '),\n document.body.appendChild(t),\n (e = 38 === t.offsetHeight),\n document.body.removeChild(t));\n }\n return e;\n };\n })(),\n o = 0;\n (Prism.hooks.add('complete', function (t) {\n var r = t.element.parentNode,\n a = r && r.getAttribute('data-line');\n r &&\n a &&\n /pre/i.test(r.nodeName) &&\n (clearTimeout(o),\n e('.line-highlight', r).forEach(function (e) {\n e.parentNode.removeChild(e);\n }),\n n(r, a),\n (o = setTimeout(i, 1)));\n }),\n window.addEventListener && window.addEventListener('hashchange', i));\n }\n })();\n !(function () {\n 'undefined' != typeof self &&\n self.Prism &&\n self.document &&\n Prism.hooks.add('complete', function (e) {\n if (e.code) {\n var t = e.element.parentNode,\n s = /\\s*\\bline-numbers\\b\\s*/;\n if (\n t &&\n /pre/i.test(t.nodeName) &&\n (s.test(t.className) || s.test(e.element.className)) &&\n !e.element.querySelector('.line-numbers-rows')\n ) {\n (s.test(e.element.className) && (e.element.className = e.element.className.replace(s, '')),\n s.test(t.className) || (t.className += ' line-numbers'));\n var n,\n a = e.code.match(/\\n(?!$)/g),\n l = a ? a.length + 1 : 1,\n r = new Array(l + 1);\n ((r = r.join('<span></span>')),\n (n = document.createElement('span')),\n n.setAttribute('aria-hidden', 'true'),\n (n.className = 'line-numbers-rows'),\n (n.innerHTML = r),\n t.hasAttribute('data-start') &&\n (t.style.counterReset = 'linenumber ' + (parseInt(t.getAttribute('data-start'), 10) - 1)),\n e.element.appendChild(n));\n }\n }\n });\n })();\n <\/script>\n <script>\n (function () {\n const $ = function (value) {\n return document.querySelector(value);\n };\n const $$ = function (value) {\n return document.querySelectorAll(value);\n };\n var nativeFramesLength = $$('.frame-row.native-frame').length;\n var allFramesLength = $$('.frame-row').length;\n function filterFrames() {\n $('.frame-preview').classList.remove('is-hidden');\n var isSelected = $('#frames-filter').checked;\n if (isSelected) {\n $$('.frame-row.native-frame').forEach(function (node) {\n node.classList.add('force-show');\n });\n } else {\n $$('.frame-row.native-frame').forEach(function (node) {\n node.classList.remove('force-show');\n });\n var activeFrame = $('.frame-row.active');\n if (activeFrame && activeFrame.classList.contains('native-frame')) {\n activeFrame.classList.remove('active');\n var firstFrame = $$('.frame-row')[0];\n if (!firstFrame) {\n return;\n }\n firstFrame.classList.add('active');\n showFrameContext(firstFrame);\n }\n }\n }\n function displayFirstView() {\n if (nativeFramesLength !== allFramesLength) {\n $('.frame-preview').classList.remove('is-hidden');\n }\n }\n function showFrameContext(frame) {\n if (!frame) {\n return;\n }\n const $frameContext = frame.querySelector('.frame-context');\n if (!$frameContext) {\n return;\n }\n var $context = $frameContext.innerHTML;\n $context = $context.trim().length === 0 ? 'Missing stack frames' : $context;\n var $line = $frameContext.getAttribute('data-line');\n var $start = $frameContext.getAttribute('data-start');\n var $file = $frameContext.getAttribute('data-file');\n var $method = $frameContext.getAttribute('data-method');\n var $lineColumn = $frameContext.getAttribute('data-line-column');\n var $language = $frameContext.getAttribute('data-extname') || 'js';\n $('#code-drop').parentNode.setAttribute('data-line', $line);\n $('#code-drop').parentNode.setAttribute('data-start', $start);\n $('#code-drop').parentNode.setAttribute('data-language', $language);\n $('#code-drop').parentNode.setAttribute('data-line-offset', Number($start) - 1);\n $('#code-drop').setAttribute('class', 'language-' + $language);\n $('#code-drop').innerHTML = $context;\n $('#frame-file').innerHTML = $file || '';\n $('#frame-method').innerHTML = [$method, $lineColumn].filter(Boolean).join(' ');\n\n Prism.highlightAll();\n }\n $$('.frame-row').forEach(function (node) {\n node.onclick = function (e) {\n $$('.frame-row').forEach(function (_node) {\n _node.classList.remove('active');\n });\n e.currentTarget.classList.add('active');\n showFrameContext(e.currentTarget);\n };\n });\n $('#frames-filter').onclick = function () {\n filterFrames();\n };\n displayFirstView();\n showFrameContext($('.frame-row.active') || $('.frame-row'));\n })();\n <\/script>\n </section>\n </body>\n</html>\n";
|
|
4
|
+
//#endregion
|
|
5
|
+
export { ONERROR_PAGE_TEMPLATE };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/lib/onerror_page.ts
|
|
2
|
+
/** Built-in error page template. */
|
|
3
|
+
const ONERROR_PAGE_TEMPLATE = `<!doctype html>
|
|
2
4
|
<html lang="en">
|
|
3
5
|
<head>
|
|
4
6
|
<meta charset="UTF-8" />
|
|
@@ -729,7 +731,7 @@
|
|
|
729
731
|
? self
|
|
730
732
|
: {},
|
|
731
733
|
Prism = (function () {
|
|
732
|
-
var e =
|
|
734
|
+
var e = /\\blang(?:uage)?-(\\w+)\\b/i,
|
|
733
735
|
t = 0,
|
|
734
736
|
n = (_self.Prism = {
|
|
735
737
|
util: {
|
|
@@ -741,10 +743,10 @@
|
|
|
741
743
|
: e
|
|
742
744
|
.replace(/&/g, '&')
|
|
743
745
|
.replace(/</g, '<')
|
|
744
|
-
.replace(
|
|
746
|
+
.replace(/\\u00a0/g, ' ');
|
|
745
747
|
},
|
|
746
748
|
type: function (e) {
|
|
747
|
-
return Object.prototype.toString.call(e).match(
|
|
749
|
+
return Object.prototype.toString.call(e).match(/\\[object (\\w+)\\]/)[1];
|
|
748
750
|
},
|
|
749
751
|
objId: function (e) {
|
|
750
752
|
return (e.__id || Object.defineProperty(e, '__id', { value: ++t }), e.__id);
|
|
@@ -820,10 +822,10 @@
|
|
|
820
822
|
highlightElement: function (t, a, r) {
|
|
821
823
|
for (var i, l, o = t; o && !e.test(o.className); ) o = o.parentNode;
|
|
822
824
|
(o && ((i = (o.className.match(e) || [, ''])[1].toLowerCase()), (l = n.languages[i])),
|
|
823
|
-
(t.className = t.className.replace(e, '').replace(
|
|
825
|
+
(t.className = t.className.replace(e, '').replace(/\\s+/g, ' ') + ' language-' + i),
|
|
824
826
|
(o = t.parentNode),
|
|
825
827
|
/pre/i.test(o.nodeName) &&
|
|
826
|
-
(o.className = o.className.replace(e, '').replace(
|
|
828
|
+
(o.className = o.className.replace(e, '').replace(/\\s+/g, ' ') + ' language-' + i));
|
|
827
829
|
var s = t.textContent,
|
|
828
830
|
u = { element: t, language: i, grammar: l, code: s };
|
|
829
831
|
if ((n.hooks.run('before-sanity-check', u), !u.code || !u.grammar))
|
|
@@ -1009,21 +1011,21 @@
|
|
|
1009
1011
|
('undefined' != typeof module && module.exports && (module.exports = Prism),
|
|
1010
1012
|
'undefined' != typeof global && (global.Prism = Prism));
|
|
1011
1013
|
((Prism.languages.markup = {
|
|
1012
|
-
comment: /<!--[
|
|
1013
|
-
prolog:
|
|
1014
|
-
doctype: /<!DOCTYPE[
|
|
1015
|
-
cdata:
|
|
1014
|
+
comment: /<!--[\\w\\W]*?-->/,
|
|
1015
|
+
prolog: /<\\?[\\w\\W]+?\\?>/,
|
|
1016
|
+
doctype: /<!DOCTYPE[\\w\\W]+?>/i,
|
|
1017
|
+
cdata: /<!\\[CDATA\\[[\\w\\W]*?]]>/i,
|
|
1016
1018
|
tag: {
|
|
1017
1019
|
pattern:
|
|
1018
|
-
|
|
1020
|
+
/<\\/?(?!\\d)[^\\s>\\/=$<]+(?:\\s+[^\\s>\\/=]+(?:=(?:("|')(?:\\\\\\1|\\\\?(?!\\1)[\\w\\W])*\\1|[^\\s'">=]+))?)*\\s*\\/?>/i,
|
|
1019
1021
|
inside: {
|
|
1020
|
-
tag: { pattern:
|
|
1021
|
-
'attr-value': { pattern: /=(?:('|")[
|
|
1022
|
-
punctuation:
|
|
1023
|
-
'attr-name': { pattern: /[
|
|
1022
|
+
tag: { pattern: /^<\\/?[^\\s>\\/]+/i, inside: { punctuation: /^<\\/?/, namespace: /^[^\\s>\\/:]+:/ } },
|
|
1023
|
+
'attr-value': { pattern: /=(?:('|")[\\w\\W]*?(\\1)|[^\\s>]+)/i, inside: { punctuation: /[=>"']/ } },
|
|
1024
|
+
punctuation: /\\/?>/,
|
|
1025
|
+
'attr-name': { pattern: /[^\\s>\\/]+/, inside: { namespace: /^[^\\s>\\/:]+:/ } },
|
|
1024
1026
|
},
|
|
1025
1027
|
},
|
|
1026
|
-
entity: /&#?[
|
|
1028
|
+
entity: /&#?[\\da-z]{1,8};/i,
|
|
1027
1029
|
}),
|
|
1028
1030
|
Prism.hooks.add('wrap', function (a) {
|
|
1029
1031
|
'entity' === a.type && (a.attributes.title = a.content.replace(/&/, '&'));
|
|
@@ -1033,21 +1035,21 @@
|
|
|
1033
1035
|
(Prism.languages.mathml = Prism.languages.markup),
|
|
1034
1036
|
(Prism.languages.svg = Prism.languages.markup));
|
|
1035
1037
|
((Prism.languages.css = {
|
|
1036
|
-
comment:
|
|
1037
|
-
atrule: { pattern: /@[
|
|
1038
|
-
url: /url
|
|
1039
|
-
selector: /[
|
|
1040
|
-
string: { pattern: /("|')(
|
|
1041
|
-
property: /(
|
|
1042
|
-
important:
|
|
1043
|
-
function: /[-a-z0-9]+(
|
|
1038
|
+
comment: /\\/\\*[\\w\\W]*?\\*\\//,
|
|
1039
|
+
atrule: { pattern: /@[\\w-]+?.*?(;|(?=\\s*\\{))/i, inside: { rule: /@[\\w-]+/ } },
|
|
1040
|
+
url: /url\\((?:(["'])(\\\\(?:\\r\\n|[\\w\\W])|(?!\\1)[^\\\\\\r\\n])*\\1|.*?)\\)/i,
|
|
1041
|
+
selector: /[^\\{\\}\\s][^\\{\\};]*?(?=\\s*\\{)/,
|
|
1042
|
+
string: { pattern: /("|')(\\\\(?:\\r\\n|[\\w\\W])|(?!\\1)[^\\\\\\r\\n])*\\1/, greedy: !0 },
|
|
1043
|
+
property: /(\\b|\\B)[\\w-]+(?=\\s*:)/i,
|
|
1044
|
+
important: /\\B!important\\b/i,
|
|
1045
|
+
function: /[-a-z0-9]+(?=\\()/i,
|
|
1044
1046
|
punctuation: /[(){};:]/,
|
|
1045
1047
|
}),
|
|
1046
1048
|
(Prism.languages.css.atrule.inside.rest = Prism.util.clone(Prism.languages.css)),
|
|
1047
1049
|
Prism.languages.markup &&
|
|
1048
1050
|
(Prism.languages.insertBefore('markup', 'tag', {
|
|
1049
1051
|
style: {
|
|
1050
|
-
pattern: /(<style[
|
|
1052
|
+
pattern: /(<style[\\w\\W]*?>)[\\w\\W]*?(?=<\\/style>)/i,
|
|
1051
1053
|
lookbehind: !0,
|
|
1052
1054
|
inside: Prism.languages.css,
|
|
1053
1055
|
alias: 'language-css',
|
|
@@ -1058,10 +1060,10 @@
|
|
|
1058
1060
|
'attr-value',
|
|
1059
1061
|
{
|
|
1060
1062
|
'style-attr': {
|
|
1061
|
-
pattern:
|
|
1063
|
+
pattern: /\\s*style=("|').*?\\1/i,
|
|
1062
1064
|
inside: {
|
|
1063
|
-
'attr-name': { pattern:
|
|
1064
|
-
punctuation:
|
|
1065
|
+
'attr-name': { pattern: /^\\s*style/i, inside: Prism.languages.markup.tag.inside },
|
|
1066
|
+
punctuation: /^\\s*=\\s*['"]|['"]\\s*$/,
|
|
1065
1067
|
'attr-value': { pattern: /.+/i, inside: Prism.languages.css },
|
|
1066
1068
|
},
|
|
1067
1069
|
alias: 'language-css',
|
|
@@ -1071,58 +1073,58 @@
|
|
|
1071
1073
|
)));
|
|
1072
1074
|
Prism.languages.clike = {
|
|
1073
1075
|
comment: [
|
|
1074
|
-
{ pattern: /(^|[
|
|
1075
|
-
{ pattern: /(^|[
|
|
1076
|
+
{ pattern: /(^|[^\\\\])\\/\\*[\\w\\W]*?\\*\\//, lookbehind: !0 },
|
|
1077
|
+
{ pattern: /(^|[^\\\\:])\\/\\/.*/, lookbehind: !0 },
|
|
1076
1078
|
],
|
|
1077
|
-
string: { pattern: /(["'])(
|
|
1079
|
+
string: { pattern: /(["'])(\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1/, greedy: !0 },
|
|
1078
1080
|
'class-name': {
|
|
1079
1081
|
pattern:
|
|
1080
|
-
/((
|
|
1082
|
+
/((?:\\b(?:class|interface|extends|implements|trait|instanceof|new)\\s+)|(?:catch\\s+\\())[a-z0-9_\\.\\\\]+/i,
|
|
1081
1083
|
lookbehind: !0,
|
|
1082
|
-
inside: { punctuation: /(
|
|
1084
|
+
inside: { punctuation: /(\\.|\\\\)/ },
|
|
1083
1085
|
},
|
|
1084
1086
|
keyword:
|
|
1085
|
-
|
|
1086
|
-
boolean:
|
|
1087
|
-
function: /[a-z0-9_]+(
|
|
1088
|
-
number:
|
|
1089
|
-
operator:
|
|
1090
|
-
punctuation: /[{}[
|
|
1087
|
+
/\\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\\b/,
|
|
1088
|
+
boolean: /\\b(true|false)\\b/,
|
|
1089
|
+
function: /[a-z0-9_]+(?=\\()/i,
|
|
1090
|
+
number: /\\b-?(?:0x[\\da-f]+|\\d*\\.?\\d+(?:e[+-]?\\d+)?)\\b/i,
|
|
1091
|
+
operator: /--?|\\+\\+?|!=?=?|<=?|>=?|==?=?|&&?|\\|\\|?|\\?|\\*|\\/|~|\\^|%/,
|
|
1092
|
+
punctuation: /[{}[\\];(),.:]/,
|
|
1091
1093
|
};
|
|
1092
1094
|
((Prism.languages.javascript = Prism.languages.extend('clike', {
|
|
1093
1095
|
keyword:
|
|
1094
|
-
|
|
1095
|
-
number:
|
|
1096
|
-
function: /[_$a-zA-Z
|
|
1097
|
-
operator:
|
|
1096
|
+
/\\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\\b/,
|
|
1097
|
+
number: /\\b-?(0x[\\dA-Fa-f]+|0b[01]+|0o[0-7]+|\\d*\\.?\\d+([Ee][+-]?\\d+)?|NaN|Infinity)\\b/,
|
|
1098
|
+
function: /[_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*(?=\\()/i,
|
|
1099
|
+
operator: /--?|\\+\\+?|!=?=?|<=?|>=?|==?=?|&&?|\\|\\|?|\\?|\\*\\*?|\\/|~|\\^|%|\\.{3}/,
|
|
1098
1100
|
})),
|
|
1099
1101
|
Prism.languages.insertBefore('javascript', 'keyword', {
|
|
1100
1102
|
regex: {
|
|
1101
|
-
pattern: /(^|[
|
|
1103
|
+
pattern: /(^|[^\\/])\\/(?!\\/)(\\[.+?]|\\\\.|[^\\/\\\\\\r\\n])+\\/[gimyu]{0,5}(?=\\s*($|[\\r\\n,.;})]))/,
|
|
1102
1104
|
lookbehind: !0,
|
|
1103
1105
|
greedy: !0,
|
|
1104
1106
|
},
|
|
1105
1107
|
}),
|
|
1106
1108
|
Prism.languages.insertBefore('javascript', 'string', {
|
|
1107
1109
|
'template-string': {
|
|
1108
|
-
pattern:
|
|
1110
|
+
pattern: /\`(?:\\\\\\\\|\\\\?[^\\\\])*?\`/,
|
|
1109
1111
|
greedy: !0,
|
|
1110
1112
|
inside: {
|
|
1111
1113
|
interpolation: {
|
|
1112
|
-
pattern:
|
|
1114
|
+
pattern: /\\$\\{[^}]+\\}/,
|
|
1113
1115
|
inside: {
|
|
1114
|
-
'interpolation-punctuation': { pattern:
|
|
1116
|
+
'interpolation-punctuation': { pattern: /^\\$\\{|\\}$/, alias: 'punctuation' },
|
|
1115
1117
|
rest: Prism.languages.javascript,
|
|
1116
1118
|
},
|
|
1117
1119
|
},
|
|
1118
|
-
string: /[
|
|
1120
|
+
string: /[\\s\\S]+/,
|
|
1119
1121
|
},
|
|
1120
1122
|
},
|
|
1121
1123
|
}),
|
|
1122
1124
|
Prism.languages.markup &&
|
|
1123
1125
|
Prism.languages.insertBefore('markup', 'tag', {
|
|
1124
1126
|
script: {
|
|
1125
|
-
pattern: /(<script[
|
|
1127
|
+
pattern: /(<script[\\w\\W]*?>)[\\w\\W]*?(?=<\\/script>)/i,
|
|
1126
1128
|
lookbehind: !0,
|
|
1127
1129
|
inside: Prism.languages.javascript,
|
|
1128
1130
|
alias: 'language-javascript',
|
|
@@ -1130,18 +1132,18 @@
|
|
|
1130
1132
|
}),
|
|
1131
1133
|
(Prism.languages.js = Prism.languages.javascript));
|
|
1132
1134
|
((Prism.languages.json = {
|
|
1133
|
-
property: /"(
|
|
1134
|
-
string: /"(?!:)(
|
|
1135
|
-
number:
|
|
1136
|
-
punctuation: /[{}[
|
|
1135
|
+
property: /"(?:\\\\.|[^\\\\"])*"(?=\\s*:)/gi,
|
|
1136
|
+
string: /"(?!:)(?:\\\\.|[^\\\\"])*"(?!:)/g,
|
|
1137
|
+
number: /\\b-?(0x[\\dA-Fa-f]+|\\d*\\.?\\d+([Ee][+-]?\\d+)?)\\b/g,
|
|
1138
|
+
punctuation: /[{}[\\]);,]/g,
|
|
1137
1139
|
operator: /:/g,
|
|
1138
|
-
boolean:
|
|
1139
|
-
null:
|
|
1140
|
+
boolean: /\\b(true|false)\\b/gi,
|
|
1141
|
+
null: /\\bnull\\b/gi,
|
|
1140
1142
|
}),
|
|
1141
1143
|
(Prism.languages.jsonp = Prism.languages.json));
|
|
1142
1144
|
((Prism.languages.typescript = Prism.languages.extend('javascript', {
|
|
1143
1145
|
keyword:
|
|
1144
|
-
|
|
1146
|
+
/\\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield|false|true|module|declare|constructor|string|Function|any|number|boolean|Array|enum|symbol|namespace|abstract|require|type)\\b/,
|
|
1145
1147
|
})),
|
|
1146
1148
|
(Prism.languages.ts = Prism.languages.typescript));
|
|
1147
1149
|
!(function () {
|
|
@@ -1149,12 +1151,12 @@
|
|
|
1149
1151
|
return Array.prototype.slice.call((t || document).querySelectorAll(e));
|
|
1150
1152
|
}
|
|
1151
1153
|
function t(e, t) {
|
|
1152
|
-
return ((t = ' ' + t + ' '), (' ' + e.className + ' ').replace(/[
|
|
1154
|
+
return ((t = ' ' + t + ' '), (' ' + e.className + ' ').replace(/[\\n\\t]/g, ' ').indexOf(t) > -1);
|
|
1153
1155
|
}
|
|
1154
1156
|
function n(e, n, i) {
|
|
1155
1157
|
for (
|
|
1156
1158
|
var o,
|
|
1157
|
-
a = n.replace(
|
|
1159
|
+
a = n.replace(/\\s+/g, '').split(','),
|
|
1158
1160
|
l = +e.getAttribute('data-line-offset') || 0,
|
|
1159
1161
|
d = r() ? parseInt : parseFloat,
|
|
1160
1162
|
c = d(getComputedStyle(e).lineHeight),
|
|
@@ -1166,7 +1168,7 @@
|
|
|
1166
1168
|
var u = +o[0],
|
|
1167
1169
|
m = +o[1] || u,
|
|
1168
1170
|
h = document.createElement('div');
|
|
1169
|
-
((h.textContent = Array(m - u + 2).join('
|
|
1171
|
+
((h.textContent = Array(m - u + 2).join('\\n')),
|
|
1170
1172
|
h.setAttribute('aria-hidden', 'true'),
|
|
1171
1173
|
(h.className = (i || '') + ' line-highlight'),
|
|
1172
1174
|
t(e, 'line-numbers') || (h.setAttribute('data-start', u), m > u && h.setAttribute('data-end', m)),
|
|
@@ -1179,7 +1181,7 @@
|
|
|
1179
1181
|
e('.temporary.line-highlight').forEach(function (e) {
|
|
1180
1182
|
e.parentNode.removeChild(e);
|
|
1181
1183
|
});
|
|
1182
|
-
var i = (t.match(
|
|
1184
|
+
var i = (t.match(/\\.([\\d,-]+)$/) || [, ''])[1];
|
|
1183
1185
|
if (i && !document.getElementById(t)) {
|
|
1184
1186
|
var r = t.slice(0, t.lastIndexOf('.')),
|
|
1185
1187
|
o = document.getElementById(r);
|
|
@@ -1231,7 +1233,7 @@
|
|
|
1231
1233
|
Prism.hooks.add('complete', function (e) {
|
|
1232
1234
|
if (e.code) {
|
|
1233
1235
|
var t = e.element.parentNode,
|
|
1234
|
-
s =
|
|
1236
|
+
s = /\\s*\\bline-numbers\\b\\s*/;
|
|
1235
1237
|
if (
|
|
1236
1238
|
t &&
|
|
1237
1239
|
/pre/i.test(t.nodeName) &&
|
|
@@ -1241,7 +1243,7 @@
|
|
|
1241
1243
|
(s.test(e.element.className) && (e.element.className = e.element.className.replace(s, '')),
|
|
1242
1244
|
s.test(t.className) || (t.className += ' line-numbers'));
|
|
1243
1245
|
var n,
|
|
1244
|
-
a = e.code.match(
|
|
1246
|
+
a = e.code.match(/\\n(?!$)/g),
|
|
1245
1247
|
l = a ? a.length + 1 : 1,
|
|
1246
1248
|
r = new Array(l + 1);
|
|
1247
1249
|
((r = r.join('<span></span>')),
|
|
@@ -1256,7 +1258,7 @@
|
|
|
1256
1258
|
}
|
|
1257
1259
|
});
|
|
1258
1260
|
})();
|
|
1259
|
-
|
|
1261
|
+
<\/script>
|
|
1260
1262
|
<script>
|
|
1261
1263
|
(function () {
|
|
1262
1264
|
const $ = function (value) {
|
|
@@ -1279,9 +1281,12 @@
|
|
|
1279
1281
|
node.classList.remove('force-show');
|
|
1280
1282
|
});
|
|
1281
1283
|
var activeFrame = $('.frame-row.active');
|
|
1282
|
-
if (activeFrame.classList.contains('native-frame')) {
|
|
1284
|
+
if (activeFrame && activeFrame.classList.contains('native-frame')) {
|
|
1283
1285
|
activeFrame.classList.remove('active');
|
|
1284
1286
|
var firstFrame = $$('.frame-row')[0];
|
|
1287
|
+
if (!firstFrame) {
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1285
1290
|
firstFrame.classList.add('active');
|
|
1286
1291
|
showFrameContext(firstFrame);
|
|
1287
1292
|
}
|
|
@@ -1293,7 +1298,13 @@
|
|
|
1293
1298
|
}
|
|
1294
1299
|
}
|
|
1295
1300
|
function showFrameContext(frame) {
|
|
1296
|
-
|
|
1301
|
+
if (!frame) {
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
const $frameContext = frame.querySelector('.frame-context');
|
|
1305
|
+
if (!$frameContext) {
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1297
1308
|
var $context = $frameContext.innerHTML;
|
|
1298
1309
|
$context = $context.trim().length === 0 ? 'Missing stack frames' : $context;
|
|
1299
1310
|
var $line = $frameContext.getAttribute('data-line');
|
|
@@ -1308,8 +1319,8 @@
|
|
|
1308
1319
|
$('#code-drop').parentNode.setAttribute('data-line-offset', Number($start) - 1);
|
|
1309
1320
|
$('#code-drop').setAttribute('class', 'language-' + $language);
|
|
1310
1321
|
$('#code-drop').innerHTML = $context;
|
|
1311
|
-
$('#frame-file').innerHTML = $file;
|
|
1312
|
-
$('#frame-method').innerHTML = $method
|
|
1322
|
+
$('#frame-file').innerHTML = $file || '';
|
|
1323
|
+
$('#frame-method').innerHTML = [$method, $lineColumn].filter(Boolean).join(' ');
|
|
1313
1324
|
|
|
1314
1325
|
Prism.highlightAll();
|
|
1315
1326
|
}
|
|
@@ -1326,9 +1337,13 @@
|
|
|
1326
1337
|
filterFrames();
|
|
1327
1338
|
};
|
|
1328
1339
|
displayFirstView();
|
|
1329
|
-
showFrameContext($('.frame-row.active'));
|
|
1340
|
+
showFrameContext($('.frame-row.active') || $('.frame-row'));
|
|
1330
1341
|
})();
|
|
1331
|
-
|
|
1342
|
+
<\/script>
|
|
1332
1343
|
</section>
|
|
1333
1344
|
</body>
|
|
1334
1345
|
</html>
|
|
1346
|
+
`;
|
|
1347
|
+
|
|
1348
|
+
//#endregion
|
|
1349
|
+
export { ONERROR_PAGE_TEMPLATE };
|
package/dist/lib/utils.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eggjs/onerror",
|
|
3
|
-
"version": "4.0.2-beta.
|
|
3
|
+
"version": "4.0.2-beta.20",
|
|
4
4
|
"description": "error handler for egg",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"egg",
|
|
@@ -28,33 +28,46 @@
|
|
|
28
28
|
"./app": "./dist/app.js",
|
|
29
29
|
"./config/config.default": "./dist/config/config.default.js",
|
|
30
30
|
"./lib/error_view": "./dist/lib/error_view.js",
|
|
31
|
+
"./lib/onerror": "./dist/lib/onerror.js",
|
|
32
|
+
"./lib/onerror_page": "./dist/lib/onerror_page.js",
|
|
31
33
|
"./lib/utils": "./dist/lib/utils.js",
|
|
32
34
|
"./types": "./dist/types.js",
|
|
33
35
|
"./package.json": "./package.json"
|
|
34
36
|
},
|
|
35
37
|
"publishConfig": {
|
|
36
|
-
"access": "public"
|
|
38
|
+
"access": "public",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": "./dist/index.js",
|
|
41
|
+
"./agent": "./dist/agent.js",
|
|
42
|
+
"./app": "./dist/app.js",
|
|
43
|
+
"./config/config.default": "./dist/config/config.default.js",
|
|
44
|
+
"./lib/error_view": "./dist/lib/error_view.js",
|
|
45
|
+
"./lib/onerror": "./dist/lib/onerror.js",
|
|
46
|
+
"./lib/onerror_page": "./dist/lib/onerror_page.js",
|
|
47
|
+
"./lib/utils": "./dist/lib/utils.js",
|
|
48
|
+
"./types": "./dist/types.js",
|
|
49
|
+
"./package.json": "./package.json"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"typecheck": "tsgo --noEmit"
|
|
37
54
|
},
|
|
38
55
|
"dependencies": {
|
|
39
56
|
"cookie": "^1.0.2",
|
|
40
|
-
"koa-onerror": "^5.0.1",
|
|
41
57
|
"mustache": "^4.2.0",
|
|
42
58
|
"stack-trace": "^0.0.10"
|
|
43
59
|
},
|
|
44
60
|
"devDependencies": {
|
|
61
|
+
"@eggjs/mock": "7.0.2-beta.20",
|
|
45
62
|
"@types/mustache": "^4.2.5",
|
|
46
63
|
"@types/stack-trace": "^0.0.33",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"egg": "4.1.2-beta.2"
|
|
64
|
+
"egg": "4.1.2-beta.20",
|
|
65
|
+
"typescript": "^5.9.3"
|
|
50
66
|
},
|
|
51
67
|
"peerDependencies": {
|
|
52
|
-
"egg": "4.1.2-beta.
|
|
68
|
+
"egg": "4.1.2-beta.20"
|
|
53
69
|
},
|
|
54
70
|
"engines": {
|
|
55
71
|
"node": ">=22.18.0"
|
|
56
|
-
},
|
|
57
|
-
"scripts": {
|
|
58
|
-
"typecheck": "tsgo --noEmit"
|
|
59
72
|
}
|
|
60
|
-
}
|
|
73
|
+
}
|