| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0ddd75b commit 104dac7
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2336,6 +2336,10 @@ error `UV_ENOSYS`. | |||
| 2336 | 2336 | <!-- YAML | |
| 2337 | 2337 | deprecated: v0.4.7 | |
| 2338 | 2338 | changes: | |
| 2339 | + - version: REPLACEME | ||
| 2340 | + pr-url: https://github.com/nodejs/node/pull/37460 | ||
| 2341 | + description: The error returned may be an `AggregateError` if more than one | ||
| 2342 | + error is returned. | ||
| 2339 | 2343 | - version: v10.0.0 | |
| 2340 | 2344 | pr-url: https://github.com/nodejs/node/pull/12562 | |
| 2341 | 2345 | description: The `callback` parameter is no longer optional. Not passing | |
@@ -2349,7 +2353,7 @@ changes: | |||
| 2349 | 2353 | * `path` {string|Buffer|URL} | |
| 2350 | 2354 | * `mode` {integer} | |
| 2351 | 2355 | * `callback` {Function} | |
| 2352 | - * `err` {Error} | ||
| 2356 | + * `err` {Error|AggregateError} | ||
| 2353 | 2357 | ||
| 2354 | 2358 | Changes the permissions on a symbolic link. No arguments other than a possible | |
| 2355 | 2359 | exception are given to the completion callback. | |
@@ -2812,6 +2816,10 @@ If `options.withFileTypes` is set to `true`, the `files` array will contain | |||
| 2812 | 2816 | <!-- YAML | |
| 2813 | 2817 | added: v0.1.29 | |
| 2814 | 2818 | changes: | |
| 2819 | + - version: REPLACEME | ||
| 2820 | + pr-url: https://github.com/nodejs/node/pull/37460 | ||
| 2821 | + description: The error returned may be an `AggregateError` if more than one | ||
| 2822 | + error is returned. | ||
| 2815 | 2823 | - version: v15.2.0 | |
| 2816 | 2824 | pr-url: https://github.com/nodejs/node/pull/35911 | |
| 2817 | 2825 | description: The options argument may include an AbortSignal to abort an | |
@@ -2843,7 +2851,7 @@ changes: | |||
| 2843 | 2851 | * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. | |
| 2844 | 2852 | * `signal` {AbortSignal} allows aborting an in-progress readFile | |
| 2845 | 2853 | * `callback` {Function} | |
| 2846 | - * `err` {Error} | ||
| 2854 | + * `err` {Error|AggregateError} | ||
| 2847 | 2855 | * `data` {string|Buffer} | |
| 2848 | 2856 | ||
| 2849 | 2857 | Asynchronously reads the entire contents of a file. | |
@@ -3390,6 +3398,10 @@ example/ | |||
| 3390 | 3398 | <!-- YAML | |
| 3391 | 3399 | added: v0.8.6 | |
| 3392 | 3400 | changes: | |
| 3401 | + - version: REPLACEME | ||
| 3402 | + pr-url: https://github.com/nodejs/node/pull/37460 | ||
| 3403 | + description: The error returned may be an `AggregateError` if more than one | ||
| 3404 | + error is returned. | ||
| 3393 | 3405 | - version: v10.0.0 | |
| 3394 | 3406 | pr-url: https://github.com/nodejs/node/pull/12562 | |
| 3395 | 3407 | description: The `callback` parameter is no longer optional. Not passing | |
@@ -3403,7 +3415,7 @@ changes: | |||
| 3403 | 3415 | * `path` {string|Buffer|URL} | |
| 3404 | 3416 | * `len` {integer} **Default:** `0` | |
| 3405 | 3417 | * `callback` {Function} | |
| 3406 | - * `err` {Error} | ||
| 3418 | + * `err` {Error|AggregateError} | ||
| 3407 | 3419 | ||
| 3408 | 3420 | Truncates the file. No arguments other than a possible exception are | |
| 3409 | 3421 | given to the completion callback. A file descriptor can also be passed as the | |
@@ -3843,6 +3855,10 @@ details. | |||
| 3843 | 3855 | <!-- YAML | |
| 3844 | 3856 | added: v0.1.29 | |
| 3845 | 3857 | changes: | |
| 3858 | + - version: REPLACEME | ||
| 3859 | + pr-url: https://github.com/nodejs/node/pull/37460 | ||
| 3860 | + description: The error returned may be an `AggregateError` if more than one | ||
| 3861 | + error is returned. | ||
| 3846 | 3862 | - version: v15.2.0 | |
| 3847 | 3863 | pr-url: https://github.com/nodejs/node/pull/35993 | |
| 3848 | 3864 | description: The options argument may include an AbortSignal to abort an | |
@@ -3883,7 +3899,7 @@ changes: | |||
| 3883 | 3899 | * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. | |
| 3884 | 3900 | * `signal` {AbortSignal} allows aborting an in-progress writeFile | |
| 3885 | 3901 | * `callback` {Function} | |
| 3886 | - * `err` {Error} | ||
| 3902 | + * `err` {Error|AggregateError} | ||
| 3887 | 3903 | ||
| 3888 | 3904 | When `file` is a filename, asynchronously writes data to the file, replacing the | |
| 3889 | 3905 | file if it already exists. `data` can be a string or a buffer. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -74,6 +74,7 @@ const { isArrayBufferView } = require('internal/util/types'); | |||
| 74 | 74 | const binding = internalBinding('fs'); | |
| 75 | 75 | const { Buffer } = require('buffer'); | |
| 76 | 76 | const { | |
| 77 | + aggregateTwoErrors, | ||
| 77 | 78 | codes: { | |
| 78 | 79 | ERR_FS_FILE_TOO_LARGE, | |
| 79 | 80 | ERR_INVALID_ARG_VALUE, | |
@@ -826,7 +827,7 @@ function truncate(path, len, callback) { | |||
| 826 | 827 | const req = new FSReqCallback(); | |
| 827 | 828 | req.oncomplete = function oncomplete(er) { | |
| 828 | 829 | fs.close(fd, (er2) => { | |
| 829 | - callback(er || er2); | ||
| 830 | + callback(aggregateTwoErrors(er2, er)); | ||
| 830 | 831 | }); | |
| 831 | 832 | }; | |
| 832 | 833 | binding.ftruncate(fd, len, req); | |
@@ -1296,7 +1297,7 @@ function lchmod(path, mode, callback) { | |||
| 1296 | 1297 | // but still try to close, and report closing errors if they occur. | |
| 1297 | 1298 | fs.fchmod(fd, mode, (err) => { | |
| 1298 | 1299 | fs.close(fd, (err2) => { | |
| 1299 | - callback(err || err2); | ||
| 1300 | + callback(aggregateTwoErrors(err2, err)); | ||
| 1300 | 1301 | }); | |
| 1301 | 1302 | }); | |
| 1302 | 1303 | }); | |
@@ -1461,11 +1462,12 @@ function lutimesSync(path, atime, mtime) { | |||
| 1461 | 1462 | ||
| 1462 | 1463 | function writeAll(fd, isUserFd, buffer, offset, length, signal, callback) { | |
| 1463 | 1464 | if (signal?.aborted) { | |
| 1465 | + const abortError = new AbortError(); | ||
| 1464 | 1466 | if (isUserFd) { | |
| 1465 | - callback(new AbortError()); | ||
| 1467 | + callback(abortError); | ||
| 1466 | 1468 | } else { | |
| 1467 | - fs.close(fd, function() { | ||
| 1468 | - callback(new AbortError()); | ||
| 1469 | + fs.close(fd, (err) => { | ||
| 1470 | + callback(aggregateTwoErrors(err, abortError)); | ||
| 1469 | 1471 | }); | |
| 1470 | 1472 | } | |
| 1471 | 1473 | return; | |
@@ -1476,8 +1478,8 @@ function writeAll(fd, isUserFd, buffer, offset, length, signal, callback) { | |||
| 1476 | 1478 | if (isUserFd) { | |
| 1477 | 1479 | callback(writeErr); | |
| 1478 | 1480 | } else { | |
| 1479 | - fs.close(fd, function close() { | ||
| 1480 | - callback(writeErr); | ||
| 1481 | + fs.close(fd, (err) => { | ||
| 1482 | + callback(aggregateTwoErrors(err, writeErr)); | ||
| 1481 | 1483 | }); | |
| 1482 | 1484 | } | |
| 1483 | 1485 | } else if (written === length) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,6 +11,7 @@ | |||
| 11 | 11 | // message may change, the code should not. | |
| 12 | 12 | ||
| 13 | 13 | const { | |
| 14 | + AggregateError, | ||
| 14 | 15 | ArrayFrom, | |
| 15 | 16 | ArrayIsArray, | |
| 16 | 17 | ArrayPrototypeIncludes, | |
@@ -36,6 +37,7 @@ const { | |||
| 36 | 37 | RangeError, | |
| 37 | 38 | ReflectApply, | |
| 38 | 39 | RegExpPrototypeTest, | |
| 40 | + SafeArrayIterator, | ||
| 39 | 41 | SafeMap, | |
| 40 | 42 | SafeWeakMap, | |
| 41 | 43 | String, | |
@@ -136,6 +138,24 @@ const maybeOverridePrepareStackTrace = (globalThis, error, trace) => { | |||
| 136 | 138 | return kNoOverride; | |
| 137 | 139 | }; | |
| 138 | 140 | ||
| 141 | + const aggregateTwoErrors = hideStackFrames((innerError, outerError) => { | ||
| 142 | + if (innerError && outerError) { | ||
| 143 | + if (ArrayIsArray(outerError.errors)) { | ||
| 144 | + // If `outerError` is already an `AggregateError`. | ||
| 145 | + ArrayPrototypePush(outerError.errors, innerError); | ||
| 146 | + return outerError; | ||
| 147 | + } | ||
| 148 | + // eslint-disable-next-line no-restricted-syntax | ||
| 149 | + const err = new AggregateError(new SafeArrayIterator([ | ||
| 150 | + outerError, | ||
| 151 | + innerError, | ||
| 152 | + ]), outerError.message); | ||
| 153 | + err.code = outerError.code; | ||
| 154 | + return err; | ||
| 155 | + } | ||
| 156 | + return innerError || outerError; | ||
| 157 | + }); | ||
| 158 | + | ||
| 139 | 159 | // Lazily loaded | |
| 140 | 160 | let util; | |
| 141 | 161 | let assert; | |
@@ -752,6 +772,7 @@ class AbortError extends Error { | |||
| 752 | 772 | } | |
| 753 | 773 | module.exports = { | |
| 754 | 774 | addCodeToName, // Exported for NghttpError | |
| 775 | + aggregateTwoErrors, | ||
| 755 | 776 | codes, | |
| 756 | 777 | dnsException, | |
| 757 | 778 | errnoException, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,6 +12,7 @@ const { FSReqCallback, close, read } = internalBinding('fs'); | |||
| 12 | 12 | ||
| 13 | 13 | const { | |
| 14 | 14 | AbortError, | |
| 15 | + aggregateTwoErrors, | ||
| 15 | 16 | } = require('internal/errors'); | |
| 16 | 17 | ||
| 17 | 18 | // Use 64kb in case the file type is not a regular file and thus do not know the | |
@@ -50,7 +51,7 @@ function readFileAfterClose(err) { | |||
| 50 | 51 | let buffer = null; | |
| 51 | 52 | ||
| 52 | 53 | if (context.err || err) | |
| 53 | - return callback(context.err || err); | ||
| 54 | + return callback(aggregateTwoErrors(err, context.err)); | ||
| 54 | 55 | ||
| 55 | 56 | try { | |
| 56 | 57 | if (context.size === 0) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -65,6 +65,7 @@ const { | |||
| 65 | 65 | }, | |
| 66 | 66 | } = require('internal/async_hooks'); | |
| 67 | 67 | const { | |
| 68 | + aggregateTwoErrors, | ||
| 68 | 69 | codes: { | |
| 69 | 70 | ERR_HTTP2_ALTSVC_INVALID_ORIGIN, | |
| 70 | 71 | ERR_HTTP2_ALTSVC_LENGTH, | |
@@ -2077,7 +2078,7 @@ class Http2Stream extends Duplex { | |||
| 2077 | 2078 | let endCheckCallbackErr; | |
| 2078 | 2079 | const done = () => { | |
| 2079 | 2080 | if (waitingForEndCheck || waitingForWriteCallback) return; | |
| 2080 | - const err = writeCallbackErr || endCheckCallbackErr; | ||
| 2081 | + const err = aggregateTwoErrors(endCheckCallbackErr, writeCallbackErr); | ||
| 2081 | 2082 | // writeGeneric does not destroy on error and | |
| 2082 | 2083 | // we cannot enable autoDestroy, | |
| 2083 | 2084 | // so make sure to destroy on error. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -152,6 +152,7 @@ function copyPrototype(src, dest, prefix) { | |||
| 152 | 152 | ||
| 153 | 153 | // Create copies of intrinsic objects | |
| 154 | 154 | [ | |
| 155 | + 'AggregateError', | ||
| 155 | 156 | 'Array', | |
| 156 | 157 | 'ArrayBuffer', | |
| 157 | 158 | 'BigInt', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,11 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | - ERR_MULTIPLE_CALLBACK | ||
| 5 | - } = require('internal/errors').codes; | ||
| 4 | + aggregateTwoErrors, | ||
| 5 | + codes: { | ||
| 6 | + ERR_MULTIPLE_CALLBACK, | ||
| 7 | + }, | ||
| 8 | + } = require('internal/errors'); | ||
| 6 | 9 | const { | |
| 7 | 10 | FunctionPrototypeCall, | |
| 8 | 11 | Symbol, | |
@@ -56,7 +59,7 @@ function destroy(err, cb) { | |||
| 56 | 59 | // If still constructing then defer calling _destroy. | |
| 57 | 60 | if (!s.constructed) { | |
| 58 | 61 | this.once(kDestroy, function(er) { | |
| 59 | - _destroy(this, err || er, cb); | ||
| 62 | + _destroy(this, aggregateTwoErrors(er, err), cb); | ||
| 60 | 63 | }); | |
| 61 | 64 | } else { | |
| 62 | 65 | _destroy(this, err, cb); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + // Flags: --expose-internals | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + require('../common'); | ||
| 5 | + const { aggregateTwoErrors } = require('internal/errors'); | ||
| 6 | + | ||
| 7 | + const originalError = new Error('original'); | ||
| 8 | + const err = new Error('second error'); | ||
| 9 | + | ||
| 10 | + originalError.code = 'ERR0'; | ||
| 11 | + err.code = 'ERR1'; | ||
| 12 | + | ||
| 13 | + throw aggregateTwoErrors(err, originalError); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + *error_aggregateTwoErrors.js:* | ||
| 2 | + throw aggregateTwoErrors(err, originalError); | ||
| 3 | + ^ | ||
| 4 | + AggregateError: original | ||
| 5 | + at Object.<anonymous> (*test*message*error_aggregateTwoErrors.js:*:*) | ||
| 6 | + at Module._compile (node:internal/modules/cjs/loader:*:*) | ||
| 7 | + at Object.Module._extensions..js (node:internal/modules/cjs/loader:*:*) | ||
| 8 | + at Module.load (node:internal/modules/cjs/loader:*:*) | ||
| 9 | + at Function.Module._load (node:internal/modules/cjs/loader:*:*) | ||
| 10 | + at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:*:*) | ||
| 11 | + at node:internal/main/run_main_module:*:* { | ||
| 12 | + code: 'ERR0' | ||
| 13 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,59 @@ | |||
| 1 | + // Flags: --expose-internals | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + require('../common'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + const { aggregateTwoErrors } = require('internal/errors'); | ||
| 7 | + | ||
| 8 | + assert.strictEqual(aggregateTwoErrors(null, null), null); | ||
| 9 | + | ||
| 10 | + { | ||
| 11 | + const err = new Error(); | ||
| 12 | + assert.strictEqual(aggregateTwoErrors(null, err), err); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + { | ||
| 16 | + const err = new Error(); | ||
| 17 | + assert.strictEqual(aggregateTwoErrors(err, null), err); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + { | ||
| 21 | + const err0 = new Error('original'); | ||
| 22 | + const err1 = new Error('second error'); | ||
| 23 | + | ||
| 24 | + err0.code = 'ERR0'; | ||
| 25 | + err1.code = 'ERR1'; | ||
| 26 | + | ||
| 27 | + const chainedError = aggregateTwoErrors(err1, err0); | ||
| 28 | + assert.strictEqual(chainedError.message, err0.message); | ||
| 29 | + assert.strictEqual(chainedError.code, err0.code); | ||
| 30 | + assert.deepStrictEqual(chainedError.errors, [err0, err1]); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + { | ||
| 34 | + const err0 = new Error('original'); | ||
| 35 | + const err1 = new Error('second error'); | ||
| 36 | + const err2 = new Error('third error'); | ||
| 37 | + | ||
| 38 | + err0.code = 'ERR0'; | ||
| 39 | + err1.code = 'ERR1'; | ||
| 40 | + err2.code = 'ERR2'; | ||
| 41 | + | ||
| 42 | + const chainedError = aggregateTwoErrors(err2, aggregateTwoErrors(err1, err0)); | ||
| 43 | + assert.strictEqual(chainedError.message, err0.message); | ||
| 44 | + assert.strictEqual(chainedError.code, err0.code); | ||
| 45 | + assert.deepStrictEqual(chainedError.errors, [err0, err1, err2]); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + { | ||
| 49 | + const err0 = new Error('original'); | ||
| 50 | + const err1 = new Error('second error'); | ||
| 51 | + | ||
| 52 | + err0.code = 'ERR0'; | ||
| 53 | + err1.code = 'ERR1'; | ||
| 54 | + | ||
| 55 | + const chainedError = aggregateTwoErrors(null, aggregateTwoErrors(err1, err0)); | ||
| 56 | + assert.strictEqual(chainedError.message, err0.message); | ||
| 57 | + assert.strictEqual(chainedError.code, err0.code); | ||
| 58 | + assert.deepStrictEqual(chainedError.errors, [err0, err1]); | ||
| 59 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments