| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,6 +56,7 @@ const { | |||
| 56 | 56 | ERR_INVALID_RETURN_VALUE, | |
| 57 | 57 | ERR_MISSING_ARGS, | |
| 58 | 58 | }, | |
| 59 | + isErrorStackTraceLimitWritable, | ||
| 59 | 60 | overrideStackTrace, | |
| 60 | 61 | } = require('internal/errors'); | |
| 61 | 62 | const AssertionError = require('internal/assert/assertion_error'); | |
@@ -282,14 +283,15 @@ function parseCode(code, offset) { | |||
| 282 | 283 | ||
| 283 | 284 | function getErrMessage(message, fn) { | |
| 284 | 285 | const tmpLimit = Error.stackTraceLimit; | |
| 286 | + const errorStackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); | ||
| 285 | 287 | // Make sure the limit is set to 1. Otherwise it could fail (<= 0) or it | |
| 286 | 288 | // does to much work. | |
| 287 | - Error.stackTraceLimit = 1; | ||
| 289 | + if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = 1; | ||
| 288 | 290 | // We only need the stack trace. To minimize the overhead use an object | |
| 289 | 291 | // instead of an error. | |
| 290 | 292 | const err = {}; | |
| 291 | 293 | ErrorCaptureStackTrace(err, fn); | |
| 292 | - Error.stackTraceLimit = tmpLimit; | ||
| 294 | + if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit; | ||
| 293 | 295 | ||
| 294 | 296 | overrideStackTrace.set(err, (_, stack) => stack); | |
| 295 | 297 | const call = err.stack[0]; | |
@@ -326,7 +328,7 @@ function getErrMessage(message, fn) { | |||
| 326 | 328 | try { | |
| 327 | 329 | // Set the stack trace limit to zero. This makes sure unexpected token | |
| 328 | 330 | // errors are handled faster. | |
| 329 | - Error.stackTraceLimit = 0; | ||
| 331 | + if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = 0; | ||
| 330 | 332 | ||
| 331 | 333 | if (filename) { | |
| 332 | 334 | if (decoder === undefined) { | |
@@ -371,7 +373,7 @@ function getErrMessage(message, fn) { | |||
| 371 | 373 | errorCache.set(identifier, undefined); | |
| 372 | 374 | } finally { | |
| 373 | 375 | // Reset limit. | |
| 374 | - Error.stackTraceLimit = tmpLimit; | ||
| 376 | + if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit; | ||
| 375 | 377 | if (fd !== undefined) | |
| 376 | 378 | closeSync(fd); | |
| 377 | 379 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,6 +24,7 @@ const { | |||
| 24 | 24 | const { | |
| 25 | 25 | validateObject, | |
| 26 | 26 | } = require('internal/validators'); | |
| 27 | + const { isErrorStackTraceLimitWritable } = require('internal/errors'); | ||
| 27 | 28 | ||
| 28 | 29 | let blue = ''; | |
| 29 | 30 | let green = ''; | |
@@ -341,7 +342,7 @@ class AssertionError extends Error { | |||
| 341 | 342 | } = options; | |
| 342 | 343 | ||
| 343 | 344 | const limit = Error.stackTraceLimit; | |
| 344 | - Error.stackTraceLimit = 0; | ||
| 345 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 345 | 346 | ||
| 346 | 347 | if (message != null) { | |
| 347 | 348 | super(String(message)); | |
@@ -436,7 +437,7 @@ class AssertionError extends Error { | |||
| 436 | 437 | } | |
| 437 | 438 | } | |
| 438 | 439 | ||
| 439 | - Error.stackTraceLimit = limit; | ||
| 440 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; | ||
| 440 | 441 | ||
| 441 | 442 | this.generatedMessage = !message; | |
| 442 | 443 | ObjectDefineProperty(this, 'name', { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,7 +33,10 @@ const { | |||
| 33 | 33 | Number, | |
| 34 | 34 | NumberIsInteger, | |
| 35 | 35 | ObjectDefineProperty, | |
| 36 | + ObjectIsExtensible, | ||
| 37 | + ObjectGetOwnPropertyDescriptor, | ||
| 36 | 38 | ObjectKeys, | |
| 39 | + ObjectPrototypeHasOwnProperty, | ||
| 37 | 40 | RangeError, | |
| 38 | 41 | ReflectApply, | |
| 39 | 42 | RegExpPrototypeTest, | |
@@ -204,6 +207,17 @@ const addCodeToName = hideStackFrames(function addCodeToName(err, name, code) { | |||
| 204 | 207 | } | |
| 205 | 208 | }); | |
| 206 | 209 | ||
| 210 | + function isErrorStackTraceLimitWritable() { | ||
| 211 | + const desc = ObjectGetOwnPropertyDescriptor(Error, 'stackTraceLimit'); | ||
| 212 | + if (desc === undefined) { | ||
| 213 | + return ObjectIsExtensible(Error); | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + return ObjectPrototypeHasOwnProperty(desc, 'writable') ? | ||
| 217 | + desc.writable : | ||
| 218 | + desc.set !== undefined; | ||
| 219 | + } | ||
| 220 | + | ||
| 207 | 221 | // A specialized Error that includes an additional info property with | |
| 208 | 222 | // additional information about the error condition. | |
| 209 | 223 | // It has the properties present in a UVException but with a custom error | |
@@ -215,10 +229,10 @@ const addCodeToName = hideStackFrames(function addCodeToName(err, name, code) { | |||
| 215 | 229 | class SystemError extends Error { | |
| 216 | 230 | constructor(key, context) { | |
| 217 | 231 | const limit = Error.stackTraceLimit; | |
| 218 | - Error.stackTraceLimit = 0; | ||
| 232 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 219 | 233 | super(); | |
| 220 | 234 | // Reset the limit and setting the name property. | |
| 221 | - Error.stackTraceLimit = limit; | ||
| 235 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; | ||
| 222 | 236 | const prefix = getMessage(key, [], this); | |
| 223 | 237 | let message = `${prefix}: ${context.syscall} returned ` + | |
| 224 | 238 | `${context.code} (${context.message})`; | |
@@ -327,10 +341,10 @@ function makeSystemErrorWithCode(key) { | |||
| 327 | 341 | function makeNodeErrorWithCode(Base, key) { | |
| 328 | 342 | return function NodeError(...args) { | |
| 329 | 343 | const limit = Error.stackTraceLimit; | |
| 330 | - Error.stackTraceLimit = 0; | ||
| 344 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 331 | 345 | const error = new Base(); | |
| 332 | 346 | // Reset the limit and setting the name property. | |
| 333 | - Error.stackTraceLimit = limit; | ||
| 347 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; | ||
| 334 | 348 | const message = getMessage(key, args, error); | |
| 335 | 349 | ObjectDefineProperty(error, 'message', { | |
| 336 | 350 | value: message, | |
@@ -434,11 +448,14 @@ function uvErrmapGet(name) { | |||
| 434 | 448 | ||
| 435 | 449 | const captureLargerStackTrace = hideStackFrames( | |
| 436 | 450 | function captureLargerStackTrace(err) { | |
| 437 | - userStackTraceLimit = Error.stackTraceLimit; | ||
| 438 | - Error.stackTraceLimit = Infinity; | ||
| 451 | + const stackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); | ||
| 452 | + if (stackTraceLimitIsWritable) { | ||
| 453 | + userStackTraceLimit = Error.stackTraceLimit; | ||
| 454 | + Error.stackTraceLimit = Infinity; | ||
| 455 | + } | ||
| 439 | 456 | ErrorCaptureStackTrace(err); | |
| 440 | 457 | // Reset the limit | |
| 441 | - Error.stackTraceLimit = userStackTraceLimit; | ||
| 458 | + if (stackTraceLimitIsWritable) Error.stackTraceLimit = userStackTraceLimit; | ||
| 442 | 459 | ||
| 443 | 460 | return err; | |
| 444 | 461 | }); | |
@@ -471,12 +488,12 @@ const uvException = hideStackFrames(function uvException(ctx) { | |||
| 471 | 488 | // the stack frames due to the `captureStackTrace()` function that is called | |
| 472 | 489 | // later. | |
| 473 | 490 | const tmpLimit = Error.stackTraceLimit; | |
| 474 | - Error.stackTraceLimit = 0; | ||
| 491 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 475 | 492 | // Pass the message to the constructor instead of setting it on the object | |
| 476 | 493 | // to make sure it is the same as the one created in C++ | |
| 477 | 494 | // eslint-disable-next-line no-restricted-syntax | |
| 478 | 495 | const err = new Error(message); | |
| 479 | - Error.stackTraceLimit = tmpLimit; | ||
| 496 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; | ||
| 480 | 497 | ||
| 481 | 498 | for (const prop of ObjectKeys(ctx)) { | |
| 482 | 499 | if (prop === 'message' || prop === 'path' || prop === 'dest') { | |
@@ -523,10 +540,10 @@ const uvExceptionWithHostPort = hideStackFrames( | |||
| 523 | 540 | // lose the stack frames due to the `captureStackTrace()` function that | |
| 524 | 541 | // is called later. | |
| 525 | 542 | const tmpLimit = Error.stackTraceLimit; | |
| 526 | - Error.stackTraceLimit = 0; | ||
| 543 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 527 | 544 | // eslint-disable-next-line no-restricted-syntax | |
| 528 | 545 | const ex = new Error(`${message}${details}`); | |
| 529 | - Error.stackTraceLimit = tmpLimit; | ||
| 546 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; | ||
| 530 | 547 | ex.code = code; | |
| 531 | 548 | ex.errno = err; | |
| 532 | 549 | ex.syscall = syscall; | |
@@ -558,10 +575,10 @@ const errnoException = hideStackFrames( | |||
| 558 | 575 | `${syscall} ${code} ${original}` : `${syscall} ${code}`; | |
| 559 | 576 | ||
| 560 | 577 | const tmpLimit = Error.stackTraceLimit; | |
| 561 | - Error.stackTraceLimit = 0; | ||
| 578 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 562 | 579 | // eslint-disable-next-line no-restricted-syntax | |
| 563 | 580 | const ex = new Error(message); | |
| 564 | - Error.stackTraceLimit = tmpLimit; | ||
| 581 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; | ||
| 565 | 582 | ex.errno = err; | |
| 566 | 583 | ex.code = code; | |
| 567 | 584 | ex.syscall = syscall; | |
@@ -602,10 +619,10 @@ const exceptionWithHostPort = hideStackFrames( | |||
| 602 | 619 | // lose the stack frames due to the `captureStackTrace()` function that | |
| 603 | 620 | // is called later. | |
| 604 | 621 | const tmpLimit = Error.stackTraceLimit; | |
| 605 | - Error.stackTraceLimit = 0; | ||
| 622 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 606 | 623 | // eslint-disable-next-line no-restricted-syntax | |
| 607 | 624 | const ex = new Error(`${syscall} ${code}${details}`); | |
| 608 | - Error.stackTraceLimit = tmpLimit; | ||
| 625 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; | ||
| 609 | 626 | ex.errno = err; | |
| 610 | 627 | ex.code = code; | |
| 611 | 628 | ex.syscall = syscall; | |
@@ -647,10 +664,10 @@ const dnsException = hideStackFrames(function(code, syscall, hostname) { | |||
| 647 | 664 | // the stack frames due to the `captureStackTrace()` function that is called | |
| 648 | 665 | // later. | |
| 649 | 666 | const tmpLimit = Error.stackTraceLimit; | |
| 650 | - Error.stackTraceLimit = 0; | ||
| 667 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 651 | 668 | // eslint-disable-next-line no-restricted-syntax | |
| 652 | 669 | const ex = new Error(message); | |
| 653 | - Error.stackTraceLimit = tmpLimit; | ||
| 670 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; | ||
| 654 | 671 | ex.errno = errno; | |
| 655 | 672 | ex.code = code; | |
| 656 | 673 | ex.syscall = syscall; | |
@@ -783,6 +800,7 @@ module.exports = { | |||
| 783 | 800 | exceptionWithHostPort, | |
| 784 | 801 | getMessage, | |
| 785 | 802 | hideStackFrames, | |
| 803 | + isErrorStackTraceLimitWritable, | ||
| 786 | 804 | isStackOverflowError, | |
| 787 | 805 | connResetException, | |
| 788 | 806 | uvErrmapGet, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -29,6 +29,7 @@ const { | |||
| 29 | 29 | popAsyncContext, | |
| 30 | 30 | } = require('internal/async_hooks'); | |
| 31 | 31 | const async_hooks = require('async_hooks'); | |
| 32 | + const { isErrorStackTraceLimitWritable } = require('internal/errors'); | ||
| 32 | 33 | ||
| 33 | 34 | // *Must* match Environment::TickInfo::Fields in src/env.h. | |
| 34 | 35 | const kHasRejectionToWarn = 1; | |
@@ -264,10 +265,10 @@ function processPromiseRejections() { | |||
| 264 | 265 | function getErrorWithoutStack(name, message) { | |
| 265 | 266 | // Reset the stack to prevent any overhead. | |
| 266 | 267 | const tmp = Error.stackTraceLimit; | |
| 267 | - Error.stackTraceLimit = 0; | ||
| 268 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 268 | 269 | // eslint-disable-next-line no-restricted-syntax | |
| 269 | 270 | const err = new Error(message); | |
| 270 | - Error.stackTraceLimit = tmp; | ||
| 271 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmp; | ||
| 271 | 272 | ObjectDefineProperty(err, 'name', { | |
| 272 | 273 | value: name, | |
| 273 | 274 | enumerable: false, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,7 +9,12 @@ const { | |||
| 9 | 9 | } = primordials; | |
| 10 | 10 | ||
| 11 | 11 | const assert = require('internal/assert'); | |
| 12 | - const { ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; | ||
| 12 | + const { | ||
| 13 | + codes: { | ||
| 14 | + ERR_INVALID_ARG_TYPE, | ||
| 15 | + }, | ||
| 16 | + isErrorStackTraceLimitWritable, | ||
| 17 | + } = require('internal/errors'); | ||
| 13 | 18 | const { validateString } = require('internal/validators'); | |
| 14 | 19 | ||
| 15 | 20 | // Lazily loaded | |
@@ -157,10 +162,10 @@ function createWarningObject(warning, type, code, ctor, detail) { | |||
| 157 | 162 | // Improve error creation performance by skipping the error frames. | |
| 158 | 163 | // They are added in the `captureStackTrace()` function below. | |
| 159 | 164 | const tmpStackLimit = Error.stackTraceLimit; | |
| 160 | - Error.stackTraceLimit = 0; | ||
| 165 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 161 | 166 | // eslint-disable-next-line no-restricted-syntax | |
| 162 | 167 | warning = new Error(warning); | |
| 163 | - Error.stackTraceLimit = tmpStackLimit; | ||
| 168 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpStackLimit; | ||
| 164 | 169 | warning.name = String(type || 'Warning'); | |
| 165 | 170 | if (code !== undefined) warning.code = code; | |
| 166 | 171 | if (detail !== undefined) warning.detail = detail; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -385,7 +385,7 @@ function isInsideNodeModules() { | |||
| 385 | 385 | // side-effect-free. Since this is currently only used for a deprecated API, | |
| 386 | 386 | // the perf implications should be okay. | |
| 387 | 387 | getStructuredStack = runInNewContext(`(function() { | |
| 388 | - Error.stackTraceLimit = Infinity; | ||
| 388 | + try { Error.stackTraceLimit = Infinity; } catch {} | ||
| 389 | 389 | return function structuredStack() { | |
| 390 | 390 | const e = new Error(); | |
| 391 | 391 | overrideStackTrace.set(e, (err, trace) => trace); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -140,6 +140,7 @@ const { | |||
| 140 | 140 | ERR_INVALID_REPL_INPUT, | |
| 141 | 141 | ERR_SCRIPT_EXECUTION_INTERRUPTED, | |
| 142 | 142 | }, | |
| 143 | + isErrorStackTraceLimitWritable, | ||
| 143 | 144 | overrideStackTrace, | |
| 144 | 145 | } = require('internal/errors'); | |
| 145 | 146 | const { sendInspectorCommand } = require('internal/util/inspector'); | |
@@ -554,9 +555,9 @@ function REPLServer(prompt, | |||
| 554 | 555 | const interrupt = new Promise((resolve, reject) => { | |
| 555 | 556 | sigintListener = () => { | |
| 556 | 557 | const tmp = Error.stackTraceLimit; | |
| 557 | - Error.stackTraceLimit = 0; | ||
| 558 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; | ||
| 558 | 559 | const err = new ERR_SCRIPT_EXECUTION_INTERRUPTED(); | |
| 559 | - Error.stackTraceLimit = tmp; | ||
| 560 | + if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmp; | ||
| 560 | 561 | reject(err); | |
| 561 | 562 | }; | |
| 562 | 563 | prioritizedSigintQueue.add(sigintListener); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,24 @@ | |||
| 1 | + // Flags: --expose-internals --frozen-intrinsics | ||
| 2 | + 'use strict'; | ||
| 3 | + require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const { E, SystemError, codes } = require('internal/errors'); | ||
| 6 | + | ||
| 7 | + E('ERR_TEST', 'custom message', SystemError); | ||
| 8 | + const { ERR_TEST } = codes; | ||
| 9 | + | ||
| 10 | + const ctx = { | ||
| 11 | + code: 'ETEST', | ||
| 12 | + message: 'code message', | ||
| 13 | + syscall: 'syscall_test', | ||
| 14 | + path: '/str', | ||
| 15 | + dest: '/str2' | ||
| 16 | + }; | ||
| 17 | + assert.throws( | ||
| 18 | + () => { throw new ERR_TEST(ctx); }, | ||
| 19 | + { | ||
| 20 | + code: 'ERR_TEST', | ||
| 21 | + name: 'SystemError', | ||
| 22 | + info: ctx, | ||
| 23 | + } | ||
| 24 | + ); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,30 @@ | |||
| 1 | + // Flags: --expose-internals | ||
| 2 | + 'use strict'; | ||
| 3 | + require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const { E, SystemError, codes } = require('internal/errors'); | ||
| 6 | + | ||
| 7 | + let stackTraceLimit; | ||
| 8 | + Reflect.defineProperty(Error, 'stackTraceLimit', { | ||
| 9 | + get() { return stackTraceLimit; }, | ||
| 10 | + set(value) { stackTraceLimit = value; }, | ||
| 11 | + }); | ||
| 12 | + | ||
| 13 | + E('ERR_TEST', 'custom message', SystemError); | ||
| 14 | + const { ERR_TEST } = codes; | ||
| 15 | + | ||
| 16 | + const ctx = { | ||
| 17 | + code: 'ETEST', | ||
| 18 | + message: 'code message', | ||
| 19 | + syscall: 'syscall_test', | ||
| 20 | + path: '/str', | ||
| 21 | + dest: '/str2' | ||
| 22 | + }; | ||
| 23 | + assert.throws( | ||
| 24 | + () => { throw new ERR_TEST(ctx); }, | ||
| 25 | + { | ||
| 26 | + code: 'ERR_TEST', | ||
| 27 | + name: 'SystemError', | ||
| 28 | + info: ctx, | ||
| 29 | + } | ||
| 30 | + ); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,27 @@ | |||
| 1 | + // Flags: --expose-internals | ||
| 2 | + 'use strict'; | ||
| 3 | + require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const { E, SystemError, codes } = require('internal/errors'); | ||
| 6 | + | ||
| 7 | + delete Error.stackTraceLimit; | ||
| 8 | + Object.seal(Error); | ||
| 9 | + | ||
| 10 | + E('ERR_TEST', 'custom message', SystemError); | ||
| 11 | + const { ERR_TEST } = codes; | ||
| 12 | + | ||
| 13 | + const ctx = { | ||
| 14 | + code: 'ETEST', | ||
| 15 | + message: 'code message', | ||
| 16 | + syscall: 'syscall_test', | ||
| 17 | + path: '/str', | ||
| 18 | + dest: '/str2' | ||
| 19 | + }; | ||
| 20 | + assert.throws( | ||
| 21 | + () => { throw new ERR_TEST(ctx); }, | ||
| 22 | + { | ||
| 23 | + code: 'ERR_TEST', | ||
| 24 | + name: 'SystemError', | ||
| 25 | + info: ctx, | ||
| 26 | + } | ||
| 27 | + ); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments