From 12fb2ffc3314b907684f6bae523fd46b03f624b6 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 11 Mar 2021 07:59:53 -0800 Subject: [PATCH] lib: use AbortError consistently Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/37715 Reviewed-By: Antoine du Hamel Reviewed-By: Trivikram Kamat Reviewed-By: Rich Trott --- lib/events.js | 32 ++++++----------- lib/fs.js | 30 ++++++++-------- lib/internal/fs/promises.js | 51 +++++++++++----------------- lib/internal/fs/read_file_context.js | 16 +++------ 4 files changed, 49 insertions(+), 80 deletions(-) diff --git a/lib/events.js b/lib/events.js index 501c05f3a4a5dd..15c69c30271aa6 100644 --- a/lib/events.js +++ b/lib/events.js @@ -51,15 +51,14 @@ const kRejection = SymbolFor('nodejs.rejection'); let spliceOne; const { - hideStackFrames, + AbortError, kEnhanceStackBeforeInspector, - codes + codes: { + ERR_INVALID_ARG_TYPE, + ERR_OUT_OF_RANGE, + ERR_UNHANDLED_ERROR + }, } = require('internal/errors'); -const { - ERR_INVALID_ARG_TYPE, - ERR_OUT_OF_RANGE, - ERR_UNHANDLED_ERROR -} = codes; const { inspect @@ -76,14 +75,6 @@ const kMaxEventTargetListeners = Symbol('events.maxEventTargetListeners'); const kMaxEventTargetListenersWarned = Symbol('events.maxEventTargetListenersWarned'); -let DOMException; -const lazyDOMException = hideStackFrames((message, name) => { - if (DOMException === undefined) - DOMException = internalBinding('messaging').DOMException; - return new DOMException(message, name); -}); - - function EventEmitter(opts) { FunctionPrototypeCall(EventEmitter.init, this, opts); } @@ -713,7 +704,7 @@ async function once(emitter, name, options = {}) { const signal = options?.signal; validateAbortSignal(signal, 'options.signal'); if (signal?.aborted) - throw lazyDOMException('The operation was aborted', 'AbortError'); + throw new AbortError(); return new Promise((resolve, reject) => { const errorListener = (err) => { emitter.removeListener(name, resolver); @@ -738,7 +729,7 @@ async function once(emitter, name, options = {}) { function abortListener() { eventTargetAgnosticRemoveListener(emitter, name, resolver); eventTargetAgnosticRemoveListener(emitter, 'error', errorListener); - reject(lazyDOMException('The operation was aborted', 'AbortError')); + reject(new AbortError()); } if (signal != null) { eventTargetAgnosticAddListener( @@ -783,9 +774,8 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) { function on(emitter, event, options) { const signal = options?.signal; validateAbortSignal(signal, 'options.signal'); - if (signal?.aborted) { - throw lazyDOMException('The operation was aborted', 'AbortError'); - } + if (signal?.aborted) + throw new AbortError(); const unconsumedEvents = []; const unconsumedPromises = []; @@ -873,7 +863,7 @@ function on(emitter, event, options) { return iterator; function abortListener() { - errorHandler(lazyDOMException('The operation was aborted', 'AbortError')); + errorHandler(new AbortError()); } function eventHandler(...args) { diff --git a/lib/fs.js b/lib/fs.js index d945798be7a1d1..bba8c752d276b3 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -80,7 +80,7 @@ const { ERR_INVALID_ARG_TYPE, ERR_FEATURE_UNAVAILABLE_ON_PLATFORM, }, - hideStackFrames, + AbortError, uvErrmapGet, uvException } = require('internal/errors'); @@ -148,13 +148,6 @@ let ReadStream; let WriteStream; let rimraf; let rimrafSync; -let DOMException; - -const lazyDOMException = hideStackFrames((message, name) => { - if (DOMException === undefined) - DOMException = internalBinding('messaging').DOMException; - return new DOMException(message, name); -}); // These have to be separate because of how graceful-fs happens to do it's // monkeypatching. @@ -324,6 +317,14 @@ function readFileAfterStat(err, stats) { context.read(); } +function checkAborted(signal, callback) { + if (signal?.aborted) { + callback(new AbortError()); + return true; + } + return false; +} + function readFile(path, options, callback) { callback = maybeCallback(callback || options); options = getOptions(options, { flag: 'r' }); @@ -342,10 +343,8 @@ function readFile(path, options, callback) { return; } - if (options.signal?.aborted) { - callback(lazyDOMException('The operation was aborted', 'AbortError')); + if (checkAborted(options.signal, callback)) return; - } const flagsNumber = stringToFlags(options.flag); path = getValidatedPath(path); @@ -1459,10 +1458,10 @@ function lutimesSync(path, atime, mtime) { function writeAll(fd, isUserFd, buffer, offset, length, signal, callback) { if (signal?.aborted) { if (isUserFd) { - callback(lazyDOMException('The operation was aborted', 'AbortError')); + callback(new AbortError()); } else { fs.close(fd, function() { - callback(lazyDOMException('The operation was aborted', 'AbortError')); + callback(new AbortError()); }); } return; @@ -1508,10 +1507,9 @@ function writeFile(path, data, options, callback) { return; } - if (options.signal?.aborted) { - callback(lazyDOMException('The operation was aborted', 'AbortError')); + if (checkAborted(options.signal, callback)) return; - } + fs.open(path, flag, options.mode, (openErr, fd) => { if (openErr) { callback(openErr); diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 125e27545cb567..5db2f7759c5238 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -33,13 +33,15 @@ const { const binding = internalBinding('fs'); const { Buffer } = require('buffer'); -const { codes, hideStackFrames } = require('internal/errors'); const { - ERR_FS_FILE_TOO_LARGE, - ERR_INVALID_ARG_TYPE, - ERR_INVALID_ARG_VALUE, - ERR_METHOD_NOT_IMPLEMENTED, -} = codes; + codes: { + ERR_FS_FILE_TOO_LARGE, + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + ERR_METHOD_NOT_IMPLEMENTED, + }, + AbortError, +} = require('internal/errors'); const { isArrayBufferView } = require('internal/util/types'); const { rimrafPromises } = require('internal/fs/rimraf'); const { @@ -93,13 +95,6 @@ const { const getDirectoryEntriesPromise = promisify(getDirents); const validateRmOptionsPromise = promisify(validateRmOptions); -let DOMException; -const lazyDOMException = hideStackFrames((message, name) => { - if (DOMException === undefined) - DOMException = internalBinding('messaging').DOMException; - return new DOMException(message, name); -}); - class FileHandle extends EventEmitterMixin(JSTransferable) { constructor(filehandle) { super(); @@ -272,15 +267,18 @@ async function fsCall(fn, handle, ...args) { } } +function checkAborted(signal) { + if (signal?.aborted) + throw new AbortError(); +} + async function writeFileHandle(filehandle, data, signal) { // `data` could be any kind of typed array. data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); let remaining = data.length; if (remaining === 0) return; do { - if (signal?.aborted) { - throw lazyDOMException('The operation was aborted', 'AbortError'); - } + checkAborted(signal); const { bytesWritten } = await write(filehandle, data, 0, MathMin(kWriteFileMaxChunkSize, data.length)); @@ -296,14 +294,11 @@ async function writeFileHandle(filehandle, data, signal) { async function readFileHandle(filehandle, options) { const signal = options?.signal; - if (signal?.aborted) { - throw lazyDOMException('The operation was aborted', 'AbortError'); - } + checkAborted(signal); + const statFields = await binding.fstat(filehandle.fd, false, kUsePromises); - if (signal?.aborted) { - throw lazyDOMException('The operation was aborted', 'AbortError'); - } + checkAborted(signal); let size; if ((statFields[1/* mode */] & S_IFMT) === S_IFREG) { @@ -321,9 +316,7 @@ async function readFileHandle(filehandle, options) { const buffers = []; const fullBuffer = noSize ? undefined : Buffer.allocUnsafeSlow(size); do { - if (signal?.aborted) { - throw lazyDOMException('The operation was aborted', 'AbortError'); - } + checkAborted(signal); let buffer; let offset; let length; @@ -693,9 +686,7 @@ async function writeFile(path, data, options) { if (path instanceof FileHandle) return writeFileHandle(path, data, options.signal); - if (options.signal?.aborted) { - throw lazyDOMException('The operation was aborted', 'AbortError'); - } + checkAborted(options.signal); const fd = await open(path, flag, options.mode); const { signal } = options; @@ -716,9 +707,7 @@ async function readFile(path, options) { if (path instanceof FileHandle) return readFileHandle(path, options); - if (options.signal?.aborted) { - throw lazyDOMException('The operation was aborted', 'AbortError'); - } + checkAborted(options.signal); const fd = await open(path, flag, 0o666); return PromisePrototypeFinally(readFileHandle(fd, options), fd.close); diff --git a/lib/internal/fs/read_file_context.js b/lib/internal/fs/read_file_context.js index 61f25f75cb9af9..5ec45882dbbdd5 100644 --- a/lib/internal/fs/read_file_context.js +++ b/lib/internal/fs/read_file_context.js @@ -10,15 +10,9 @@ const { Buffer } = require('buffer'); const { FSReqCallback, close, read } = internalBinding('fs'); -const { hideStackFrames } = require('internal/errors'); - - -let DOMException; -const lazyDOMException = hideStackFrames((message, name) => { - if (DOMException === undefined) - DOMException = internalBinding('messaging').DOMException; - return new DOMException(message, name); -}); +const { + AbortError, +} = require('internal/errors'); // Use 64kb in case the file type is not a regular file and thus do not know the // actual file size. Increasing the value further results in more frequent over @@ -95,9 +89,7 @@ class ReadFileContext { let length; if (this.signal?.aborted) { - return this.close( - lazyDOMException('The operation was aborted', 'AbortError') - ); + return this.close(new AbortError()); } if (this.size === 0) { buffer = Buffer.allocUnsafeSlow(kReadFileUnknownBufferLength);