mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-26 06:34:20 +08:00
The error identity cache (scr_dyn_from_error) keeps one checked-dynamic node per error so a crossing error compares reference-equal and keeps the properties set on it. It retained both sides for the whole process, so every error that crossed a checked-dynamic boundary (a caught error read through a cast, an error delivered to an untyped callback, a dns failure, a warning) stayed alive until exit: 100,000 caught AssertionErrors read through a cast grew the resident set by about 210 MiB. The cache now sweeps itself. An entry whose error and node are referenced only by the cache is unreachable (a node holds no reference to its error; a registered subclass box holds one, and a spawnSync error's `error` property refers to its own node), so a sweep releases both sides. Sweeps run when the cache doubles past the entries the last sweep kept, so they cost amortized constant time per crossing. The cache is per thread, and objects shared across threads are published (immortal), so a sweep never races another thread's reference. Live errors and live nodes keep their entries: identity, rethrowing the same instance, isNativeError and kind checks are unchanged. scr_error_set_prop sets an own property on an error's node; dns, assert, cipher, crypto, util.callbackify and warning errors use it for the properties they attach. util.inspect of a runtime error renders through its node: Node's own properties follow the bracket form in key order (a system error's errno, code, syscall and path, and the extra properties a throw site attached), and an AssertionError renders at depth 0 with long string actual/expected values shortened, as its custom inspect does. A node that contains itself renders as Node's <ref *1>/[Circular *1]. child_process errors carry Node's own properties: - execSync and execFileSync: status, signal, output, pid, stdout and stderr (Buffers, or strings with an encoding option); a spawn failure or timeout adds errno, syscall, path, spawnargs and error first. - execFile's callback and the promisified execFile/exec: code (the exit status, or null after a signal), killed, signal and cmd, with stdout and stderr when promisified; a spawn failure has errno, code, syscall, path, spawnargs and cmd. The sync forms echo the captured stderr before a timeout throw too, as Node's inheritStderr does. The cp.execSync libCall takes a flag for Buffer outputs. An error's own `stack` stays non-enumerable when assigned through its node. A worker's record-source table is freed when the worker exits.
6 lines
1.3 KiB
Plaintext
6 lines
1.3 KiB
Plaintext
`process.argv[0]` is `"scriptc"`, `process.argv[1]` is the binary's path, and program arguments begin at index 2. In programs that use `node:test`, a leading `--test-update-snapshots` argument is Node's snapshot update flag: it is kept out of `process.argv` and appears in `process.execArgv`, which is otherwise `[]`. `process.version` and `process.versions.node` report the Node.js release the runtime is verified against.
|
|
|
|
Uncaught exceptions print `Uncaught <value>` to stderr instead of Node.js's source excerpt and stack-trace block; thrown strings and numbers print their value. Exit codes and output written before the exception are preserved. Runtime errors expose `message` and Node's `code` as typed members. The other own properties Node gives them, such as a system error's `errno`, `syscall`, and `path`, a child process error's `status`, `stdout`, and `stderr`, or an assertion error's `actual` and `expected`, are readable through an untyped view of the error (for example a cast of a caught value) and appear in `util.inspect` output.
|
|
|
|
Errors carry no stack frames. `console.log` and `util.inspect` print an Error in Node's stackless form, `[TypeError: message]`, where Node prints `TypeError: message` followed by stack frames; the two agree when `Error.stackTraceLimit` is `0`.
|