From 7095355b36a58fb8eef2109ba152e6518098a011 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 6 Dec 2023 09:50:28 +0100 Subject: [PATCH 1/2] fix: more sensible stack trace from dump error --- lib/api/readable.js | 42 ++++++++++++++++++------------------------ lib/core/errors.js | 12 +++++++++++- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/api/readable.js b/lib/api/readable.js index 356a03aedd9..c6e142b8ab9 100644 --- a/lib/api/readable.js +++ b/lib/api/readable.js @@ -4,7 +4,7 @@ const assert = require('assert') const { Readable } = require('stream') -const { RequestAbortedError, NotSupportedError, InvalidArgumentError } = require('../core/errors') +const { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = require('../core/errors') const util = require('../core/util') const { ReadableStreamFrom, toUSVString } = require('../core/util') @@ -163,37 +163,31 @@ module.exports = class BodyReadable extends Readable { return this[kBody] } - dump (opts) { - let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 - const signal = opts && opts.signal - - if (signal) { - try { - if (typeof signal !== 'object' || !('aborted' in signal)) { - throw new InvalidArgumentError('signal must be an AbortSignal') - } - util.throwIfAborted(signal) - } catch (err) { - return Promise.reject(err) - } + async dump (opts) { + let limit = Number.isFinite(opts?.limit) ? opts.limit : 262144 + const signal = opts?.signal + + if (signal != null && (typeof signal !== 'object' || !('aborted' in signal))) { + throw new InvalidArgumentError('signal must be an AbortSignal') } + signal?.throwIfAborted() + if (this._readableState.closeEmitted) { - return Promise.resolve(null) + return null } - return new Promise((resolve, reject) => { - const signalListenerCleanup = signal - ? util.addAbortListener(signal, () => { - this.destroy() - }) - : noop + return await new Promise((resolve, reject) => { + const onAbort = () => { + this.destroy(signal.reason ?? new AbortError()) + } + signal?.addEventListener('abort', onAbort) this .on('close', function () { - signalListenerCleanup() - if (signal && signal.aborted) { - reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) + signal?.removeEventListener('abort', onAbort) + if (signal?.aborted) { + reject(signal.reason ?? new AbortError()) } else { resolve(null) } diff --git a/lib/core/errors.js b/lib/core/errors.js index 7af704b462a..aac259fd2cf 100644 --- a/lib/core/errors.js +++ b/lib/core/errors.js @@ -82,7 +82,16 @@ class InvalidReturnValueError extends UndiciError { } } -class RequestAbortedError extends UndiciError { +class AbortError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, RequestAbortedError) + this.name = 'AbortError' + this.message = message || 'The operation was aborted' + } +} + +class RequestAbortedError extends AbortError { constructor (message) { super(message) Error.captureStackTrace(this, RequestAbortedError) @@ -207,6 +216,7 @@ class RequestRetryError extends UndiciError { } module.exports = { + AbortError, HTTPParserError, UndiciError, HeadersTimeoutError, From 769d9e60b938ce573d4f2a9216dd12d6bccc9c05 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 6 Dec 2023 11:23:29 +0100 Subject: [PATCH 2/2] Update lib/core/errors.js Co-authored-by: Carlos Fuentes --- lib/core/errors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/errors.js b/lib/core/errors.js index aac259fd2cf..e9adb2064da 100644 --- a/lib/core/errors.js +++ b/lib/core/errors.js @@ -85,7 +85,7 @@ class InvalidReturnValueError extends UndiciError { class AbortError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, RequestAbortedError) + Error.captureStackTrace(this, AbortError) this.name = 'AbortError' this.message = message || 'The operation was aborted' }