-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherror.ts
More file actions
97 lines (91 loc) · 4 KB
/
error.ts
File metadata and controls
97 lines (91 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/**
* @fileoverview Safe references to `Error` and its subclass constructors,
* plus V8's stack-trace API.
*
* `Error.isError` is ES2025; `captureStackTrace` / `prepareStackTrace` /
* `stackTraceLimit` are V8 extensions absent on JavaScriptCore and
* SpiderMonkey. Each is typed `Function | undefined` so non-V8 importers
* stay safe.
*/
export const ErrorCtor: ErrorConstructor = Error
// Error subclasses commonly thrown in validation paths.
export const AggregateErrorCtor: AggregateErrorConstructor = AggregateError
export const EvalErrorCtor: EvalErrorConstructor = EvalError
export const RangeErrorCtor: RangeErrorConstructor = RangeError
export const ReferenceErrorCtor: ReferenceErrorConstructor = ReferenceError
export const SyntaxErrorCtor: SyntaxErrorConstructor = SyntaxError
export const TypeErrorCtor: TypeErrorConstructor = TypeError
export const URIErrorCtor: URIErrorConstructor = URIError
// ─── Error (static) ────────────────────────────────────────────────────
// `Error.isError` is ES2025 (Node 22.18+). Older Node falls back to
// `instanceof Error` via the polyfill in src/errors.ts. The primordial
// reference is typed `Function | undefined` so callers in older
// environments don't crash at import time.
export const ErrorIsError: ((value: unknown) => value is Error) | undefined = (
Error as { isError?: (v: unknown) => v is Error }
).isError
// V8-specific stack trace API. See https://v8.dev/docs/stack-trace-api.
// These are present on V8 (Node, Chromium, Deno) but not in
// JavaScriptCore / SpiderMonkey, so each is typed `| undefined` to keep
// non-V8 importers safe.
// `Error.captureStackTrace(targetObject, constructorOpt?)` — attaches a
// `.stack` property to `targetObject`. Captured at load time so callers
// can't intercept by overwriting the global later.
export const ErrorCaptureStackTrace:
| ((targetObject: object, constructorOpt?: Function) => void)
| undefined = (
Error as {
captureStackTrace?: (
targetObject: object,
constructorOpt?: Function,
) => void
}
).captureStackTrace
// `Error.prepareStackTrace` — invoked by V8 when `error.stack` is first
// read. Captured at load time so we have the engine default even if
// user code later overwrites it (some libraries clobber this for
// source-map remapping). Setter not exposed — assigning to the
// primordial wouldn't affect V8's lookup, which always reads
// `Error.prepareStackTrace` fresh.
export const ErrorPrepareStackTrace:
| ((error: Error, structuredStackTrace: NodeJS.CallSite[]) => unknown)
| undefined = (
Error as {
prepareStackTrace?: (
error: Error,
structuredStackTrace: NodeJS.CallSite[],
) => unknown
}
).prepareStackTrace
// `Error.stackTraceLimit` — max frames V8 captures per stack. May be a
// data property (today on Node) or an accessor (some bundler shims).
// Returning a function avoids capturing a stale snapshot — callers that
// need the live value invoke `ErrorStackTraceLimit()` and get whatever
// V8 currently reports.
//
// `__lookupGetter__` is "annex B legacy" but supported in V8 / SpiderMonkey
// / JavaScriptCore. We probe it once at load time and fall back to
// reading the data property if no accessor exists.
const _stackTraceLimitGetter: (() => number) | undefined = (() => {
const getter = (
Error as unknown as {
__lookupGetter__?: (key: string) => (() => number) | undefined
}
).__lookupGetter__?.('stackTraceLimit')
// V8 always exposes __lookupGetter__ for Error.stackTraceLimit.
/* c8 ignore start */
if (typeof getter === 'function') {
return () => getter.call(Error)
}
return undefined
/* c8 ignore stop */
})()
export function ErrorStackTraceLimit(): number | undefined {
// _stackTraceLimitGetter is always set on V8.
/* c8 ignore start */
if (_stackTraceLimitGetter) {
return _stackTraceLimitGetter()
}
return (Error as { stackTraceLimit?: number }).stackTraceLimit
/* c8 ignore stop */
}