diff options
Diffstat (limited to 'lib/internal/errors.js')
-rw-r--r-- | lib/internal/errors.js | 79 |
1 files changed, 59 insertions, 20 deletions
diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 536778db43..0112eb6278 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -18,7 +18,7 @@ const codes = {}; const { kMaxLength } = internalBinding('buffer'); const { defineProperty } = Object; -let useOriginalName = false; +let excludedStackFn; // Lazily loaded let util; @@ -49,7 +49,15 @@ function lazyBuffer() { // and may have .path and .dest. class SystemError extends Error { constructor(key, context) { - super(); + if (excludedStackFn === undefined) { + super(); + } else { + const limit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + super(); + // Reset the limit and setting the name property. + Error.stackTraceLimit = limit; + } const prefix = getMessage(key, [], this); let message = `${prefix}: ${context.syscall} returned ` + `${context.code} (${context.message})`; @@ -148,7 +156,15 @@ function makeSystemErrorWithCode(key) { function makeNodeErrorWithCode(Base, key) { return class NodeError extends Base { constructor(...args) { - super(); + if (excludedStackFn === undefined) { + super(); + } else { + const limit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + super(); + // Reset the limit and setting the name property. + Error.stackTraceLimit = limit; + } const message = getMessage(key, args, this); Object.defineProperty(this, 'message', { value: message, @@ -178,9 +194,30 @@ function makeNodeErrorWithCode(Base, key) { }; } +// This function removes unnecessary frames from Node.js core errors. +function hideStackFrames(fn) { + return function hidden(...args) { + // Make sure the most outer `hideStackFrames()` function is used. + let setStackFn = false; + if (excludedStackFn === undefined) { + excludedStackFn = hidden; + setStackFn = true; + } + try { + return fn(...args); + } finally { + if (setStackFn === true) { + excludedStackFn = undefined; + } + } + }; +} + function addCodeToName(err, name, code) { - if (useOriginalName) { - return; + // Set the stack + if (excludedStackFn !== undefined) { + // eslint-disable-next-line no-restricted-syntax + Error.captureStackTrace(err, excludedStackFn); } // Add the error code to the name to include it in the stack trace. err.name = `${name} [${code}]`; @@ -308,6 +345,7 @@ function uvException(ctx) { err[prop] = ctx[prop]; } + // TODO(BridgeAR): Show the `code` property as part of the stack. err.code = code; if (path) { err.path = path; @@ -316,7 +354,7 @@ function uvException(ctx) { err.dest = dest; } - Error.captureStackTrace(err, uvException); + Error.captureStackTrace(err, excludedStackFn || uvException); return err; } @@ -358,7 +396,7 @@ function uvExceptionWithHostPort(err, syscall, address, port) { ex.port = port; } - Error.captureStackTrace(ex, uvExceptionWithHostPort); + Error.captureStackTrace(ex, excludedStackFn || uvExceptionWithHostPort); return ex; } @@ -386,7 +424,7 @@ function errnoException(err, syscall, original) { ex.code = ex.errno = code; ex.syscall = syscall; - Error.captureStackTrace(ex, errnoException); + Error.captureStackTrace(ex, excludedStackFn || errnoException); return ex; } @@ -434,7 +472,7 @@ function exceptionWithHostPort(err, syscall, address, port, additional) { ex.port = port; } - Error.captureStackTrace(ex, exceptionWithHostPort); + Error.captureStackTrace(ex, excludedStackFn || exceptionWithHostPort); return ex; } @@ -473,7 +511,8 @@ function dnsException(code, syscall, hostname) { if (hostname) { ex.hostname = hostname; } - Error.captureStackTrace(ex, dnsException); + + Error.captureStackTrace(ex, excludedStackFn || dnsException); return ex; } @@ -523,21 +562,19 @@ function oneOf(expected, thing) { } module.exports = { + addCodeToName, // Exported for NghttpError + codes, dnsException, errnoException, exceptionWithHostPort, + getMessage, + hideStackFrames, + isStackOverflowError, uvException, uvExceptionWithHostPort, - isStackOverflowError, - getMessage, SystemError, - codes, // This is exported only to facilitate testing. - E, - // This allows us to tell the type of the errors without using - // instanceof, which is necessary in WPT harness. - get useOriginalName() { return useOriginalName; }, - set useOriginalName(value) { useOriginalName = value; } + E }; // To declare an error message, use the E(sym, val, def) function above. The sym @@ -556,7 +593,6 @@ module.exports = { // Note: Please try to keep these in alphabetical order // // Note: Node.js specific errors must begin with the prefix ERR_ - E('ERR_AMBIGUOUS_ARGUMENT', 'The "%s" argument is ambiguous. %s', TypeError); E('ERR_ARG_NOT_ITERABLE', '%s must be iterable', TypeError); E('ERR_ASSERTION', '%s', Error); @@ -630,7 +666,10 @@ E('ERR_ENCODING_INVALID_ENCODED_DATA', function(encoding, ret) { }, TypeError); E('ERR_ENCODING_NOT_SUPPORTED', 'The "%s" encoding is not supported', RangeError); -E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value', Error); +E('ERR_FALSY_VALUE_REJECTION', function(reason) { + this.reason = reason; + return 'Promise was rejected with falsy value'; +}, Error); E('ERR_FS_FILE_TOO_LARGE', 'File size (%s) is greater than possible Buffer: ' + `${kMaxLength} bytes`, RangeError); |