diff options
author | 2021-09-07 03:21:58 -0700 | |
---|---|---|
committer | 2021-09-07 03:21:58 -0700 | |
commit | 1d1a70c21fc1f6e9e618cb52262e21bc37ac4be3 (patch) | |
tree | c942103d08048141f417a4b75130326b53b73cb9 /examples | |
parent | d59e7b27b0b525126fe5011f5ab393f9f5e6659a (diff) | |
download | bun-1d1a70c21fc1f6e9e618cb52262e21bc37ac4be3.tar.gz bun-1d1a70c21fc1f6e9e618cb52262e21bc37ac4be3.tar.zst bun-1d1a70c21fc1f6e9e618cb52262e21bc37ac4be3.zip |
WIP error css
Former-commit-id: 36f03bf491cf274f68361e334a706538464ee271
Diffstat (limited to 'examples')
-rw-r--r-- | examples/hello-next/babel.js.REMOVED.git-id | 1 | ||||
-rw-r--r-- | examples/hello-next/bun-framework-next/bun-error/powered-by.png | bin | 0 -> 2863 bytes | |||
-rw-r--r-- | examples/hello-next/bun-framework-next/bun-error/powered-by.webp | bin | 0 -> 1316 bytes | |||
-rw-r--r-- | examples/hello-next/bun-framework-next/bun-runtime-error.ts | 163 |
4 files changed, 163 insertions, 1 deletions
diff --git a/examples/hello-next/babel.js.REMOVED.git-id b/examples/hello-next/babel.js.REMOVED.git-id deleted file mode 100644 index c6e41fc71..000000000 --- a/examples/hello-next/babel.js.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2e5ce1979cde7a27f105fc408e375bbc6a9d78d
\ No newline at end of file diff --git a/examples/hello-next/bun-framework-next/bun-error/powered-by.png b/examples/hello-next/bun-framework-next/bun-error/powered-by.png Binary files differnew file mode 100644 index 000000000..7e71f1357 --- /dev/null +++ b/examples/hello-next/bun-framework-next/bun-error/powered-by.png diff --git a/examples/hello-next/bun-framework-next/bun-error/powered-by.webp b/examples/hello-next/bun-framework-next/bun-error/powered-by.webp Binary files differnew file mode 100644 index 000000000..0f48488ea --- /dev/null +++ b/examples/hello-next/bun-framework-next/bun-error/powered-by.webp diff --git a/examples/hello-next/bun-framework-next/bun-runtime-error.ts b/examples/hello-next/bun-framework-next/bun-runtime-error.ts new file mode 100644 index 000000000..331040b36 --- /dev/null +++ b/examples/hello-next/bun-framework-next/bun-runtime-error.ts @@ -0,0 +1,163 @@ +// Based on https://github.com/stacktracejs/error-stack-parser/blob/master/error-stack-parser.js + +import type { + StackFrame as StackFrameType, + StackFramePosition, + StackFrameScope, +} from "../../../src/api/schema"; + +export class StackFrame implements StackFrameType { + function_name: string; + file: string; + position: StackFramePosition; + scope: StackFrameScope; + lineText: string = ""; + constructor({ + functionName: function_name = "", + fileName: file = "", + lineNumber: line = -1, + columnNumber: column = -1, + source = "", + }) { + this.function_name = function_name; + this.file = file; + if (source) this.lineText = source; + this.scope = 3; + this.position = { + line: line, + source_offset: -1, + line_start: -1, + line_stop: -1, + column_start: column, + column_stop: -1, + expression_start: -1, + expression_stop: -1, + }; + } +} + +const FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/; +const CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m; +const SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code])?$/; + +export default class RuntimeError { + original: Error; + stack: StackFrame[]; + + static from(error: Error) { + const runtime = new RuntimeError(); + runtime.original = error; + runtime.stack = this.parseStack(error); + return RuntimeError; + } + + /** + * Given an Error object, extract the most information from it. + * + * @param {Error} error object + * @return {Array} of StackFrames + */ + static parseStack(error) { + if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) { + return this.parseV8OrIE(error); + } else if (error.stack) { + return this.parseFFOrSafari(error); + } else { + return []; + } + } + + // Separate line and column numbers from a string of the form: (URI:Line:Column) + static extractLocation(urlLike) { + // Fail-fast but return locations like "(native)" + if (urlLike.indexOf(":") === -1) { + return [urlLike]; + } + + var regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; + var parts = regExp.exec(urlLike.replace(/[()]/g, "")); + return [parts[1], parts[2] || undefined, parts[3] || undefined]; + } + + static parseV8OrIE(error) { + var filtered = error.stack.split("\n").filter(function (line) { + return !!line.match(CHROME_IE_STACK_REGEXP); + }, this); + + return filtered.map(function (line) { + if (line.indexOf("(eval ") > -1) { + // Throw away eval information until we implement stacktrace.js/stackframe#8 + line = line + .replace(/eval code/g, "eval") + .replace(/(\(eval at [^()]*)|(\),.*$)/g, ""); + } + var sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "("); + + // capture and preseve the parenthesized location "(/foo/my bar.js:12:87)" in + // case it has spaces in it, as the string is split on \s+ later on + var location = sanitizedLine.match(/ (\((.+):(\d+):(\d+)\)$)/); + + // remove the parenthesized location from the line, if it was matched + sanitizedLine = location + ? sanitizedLine.replace(location[0], "") + : sanitizedLine; + + var tokens = sanitizedLine.split(/\s+/).slice(1); + // if a location was matched, pass it to extractLocation() otherwise pop the last token + var locationParts = this.extractLocation( + location ? location[1] : tokens.pop() + ); + var functionName = tokens.join(" ") || undefined; + var fileName = + ["eval", "<anonymous>"].indexOf(locationParts[0]) > -1 + ? undefined + : locationParts[0]; + + return new StackFrame({ + functionName: functionName, + fileName: fileName, + lineNumber: locationParts[1], + columnNumber: locationParts[2], + source: line, + }); + }, this); + } + + static parseFFOrSafari(error) { + var filtered = error.stack.split("\n").filter(function (line) { + return !line.match(SAFARI_NATIVE_CODE_REGEXP); + }, this); + + return filtered.map(function (line) { + // Throw away eval information until we implement stacktrace.js/stackframe#8 + if (line.indexOf(" > eval") > -1) { + line = line.replace( + / line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, + ":$1" + ); + } + + if (line.indexOf("@") === -1 && line.indexOf(":") === -1) { + // Safari eval frames only have function names and nothing else + return new StackFrame({ + functionName: line, + }); + } else { + var functionNameRegex = /((.*".+"[^@]*)?[^@]*)(?:@)/; + var matches = line.match(functionNameRegex); + var functionName = matches && matches[1] ? matches[1] : undefined; + var locationParts = this.extractLocation( + line.replace(functionNameRegex, "") + ); + + return new StackFrame({ + functionName: functionName, + fileName: locationParts[0], + lineNumber: locationParts[1], + columnNumber: locationParts[2], + source: line, + }); + } + }, this); + } +} |