From 6d192f987ef62623de3f2d9d86ff526d38f12265 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Thu, 30 Jul 2020 18:03:08 +0200 Subject: [PATCH] Prevent `Uncaught (in promise) AbortException` when running the unit-tests These errors can/will occur if data is still loading when the document is destroyed, which is the case in the API unit-tests that load the `tracemonkey.pdf` file. While this patch prevents these kind of problems, and thus allows us to update Jasmine again, I cannot help but thinking that it's slightly "hacky". Basically, we'll simply catch and ignore (some) rejected promises once the document is destroyed and/or its data loading is aborted. However, I don't *think* that these changes should cause issues in general, since we don't really care about errors once document destruction has started (note e.g. the fair number of `catch` handlers ignoring `AbortException`s already). --- src/core/chunked_stream.js | 26 ++++++++++++++++---------- src/display/api.js | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/core/chunked_stream.js b/src/core/chunked_stream.js index c764c7181..a4ba183b5 100644 --- a/src/core/chunked_stream.js +++ b/src/core/chunked_stream.js @@ -410,18 +410,24 @@ class ChunkedStreamManager { requestIds.push(requestId); } - if (!chunksToRequest.length) { - return capability.promise; + if (chunksToRequest.length > 0) { + const groupedChunksToRequest = this.groupChunks(chunksToRequest); + for (const groupedChunk of groupedChunksToRequest) { + const begin = groupedChunk.beginChunk * this.chunkSize; + const end = Math.min( + groupedChunk.endChunk * this.chunkSize, + this.length + ); + this.sendRequest(begin, end); + } } - const groupedChunksToRequest = this.groupChunks(chunksToRequest); - for (const groupedChunk of groupedChunksToRequest) { - const begin = groupedChunk.beginChunk * this.chunkSize; - const end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length); - this.sendRequest(begin, end); - } - - return capability.promise; + return capability.promise.catch(reason => { + if (this.aborted) { + return; // Ignoring any pending requests after abort. + } + throw reason; + }); } getStream() { diff --git a/src/display/api.js b/src/display/api.js index 140dafc49..bd48ca824 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -2048,6 +2048,13 @@ class WorkerTransport { sink.onCancel = reason => { this._fullReader.cancel(reason); + + sink.ready.catch(readyReason => { + if (this.destroyed) { + return; // Ignore any pending requests if the worker was terminated. + } + throw readyReason; + }); }; }); @@ -2127,6 +2134,13 @@ class WorkerTransport { sink.onCancel = reason => { rangeReader.cancel(reason); + + sink.ready.catch(readyReason => { + if (this.destroyed) { + return; // Ignore any pending requests if the worker was terminated. + } + throw readyReason; + }); }; });