diff --git a/.changeset/afraid-beers-listen.md b/.changeset/afraid-beers-listen.md new file mode 100644 index 000000000..a63d1abc4 --- /dev/null +++ b/.changeset/afraid-beers-listen.md @@ -0,0 +1,6 @@ +--- +"@uppy/utils": patch +"@uppy/xhr-upload": patch +--- + +Fix `complete` event never firing for XHR and make sure the fetch aborts immediately if Uppy is cancelled before the fetch starts. diff --git a/packages/@uppy/utils/src/fetcher.ts b/packages/@uppy/utils/src/fetcher.ts index c8d9368c8..87e0540db 100644 --- a/packages/@uppy/utils/src/fetcher.ts +++ b/packages/@uppy/utils/src/fetcher.ts @@ -101,13 +101,6 @@ export function fetcher( xhr.responseType = responseType } - signal?.addEventListener('abort', () => { - xhr.abort() - // Using DOMException for abort errors aligns with - // the convention established by the Fetch API. - reject(new DOMException('Aborted', 'AbortError')) - }) - xhr.onload = async () => { try { await onAfterResponse(xhr, retryCount) @@ -145,6 +138,21 @@ export function fetcher( }) } + function abort() { + xhr.abort() + // Using DOMException for abort errors aligns with + // the convention established by the Fetch API. + reject(new DOMException('Aborted', 'AbortError')) + } + + signal?.addEventListener('abort', abort) + + if (signal?.aborted) { + // in case the signal was already aborted + abort() + return + } + await onBeforeRequest(xhr, retryCount) xhr.send(body) }) diff --git a/packages/@uppy/xhr-upload/src/index.ts b/packages/@uppy/xhr-upload/src/index.ts index a4a461f75..d41d1e9f3 100644 --- a/packages/@uppy/xhr-upload/src/index.ts +++ b/packages/@uppy/xhr-upload/src/index.ts @@ -235,11 +235,13 @@ export default class XHRUpload< if (event.lengthComputable) { for (const { id } of files) { const file = this.uppy.getFile(id) - this.uppy.emit('upload-progress', file, { - uploadStarted: file.progress.uploadStarted ?? 0, - bytesUploaded: (event.loaded / event.total) * file.size!, - bytesTotal: file.size, - }) + if (file != null) { + this.uppy.emit('upload-progress', file, { + uploadStarted: file.progress.uploadStarted ?? 0, + bytesUploaded: (event.loaded / event.total) * file.size!, + bytesTotal: file.size, + }) + } } } }, @@ -409,7 +411,7 @@ export default class XHRUpload< }) try { - await uppyFetch().abortOn(controller.signal) + await uppyFetch() } catch (error) { // TODO: create formal error with name 'AbortError' (this comes from RateLimitedQueue) if (error.message !== 'Cancelled') { @@ -450,7 +452,7 @@ export default class XHRUpload< this.uppy.once('cancel-all', abort) try { - await uppyFetch().abortOn(controller.signal) + await uppyFetch() } catch (error) { // TODO: create formal error with name 'AbortError' (this comes from RateLimitedQueue) if (error.message !== 'Cancelled') {