From 9de30c4ff01a3bbd40d74a86a64d90ffc1719ed0 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 4 Dec 2021 16:40:48 +0100 Subject: [PATCH] Ensure that the viewer handles `BaseViewer` initialization failures *This patch can be tested e.g. with the `poppler-85140-0.pdf` document from the test-suite.* For some sufficiently corrupt documents the `getDocument` call will succeed, but fetching even the very first page fails. Currently we only print error messages (in the console) from the `{BaseViewer, PDFThumbnailViewer}.setDocument` methods, but don't actually provide these errors to allow the viewer to handle them properly. In practice this means that the GENERIC viewer won't display the `errorWrapper`, and in the MOZCENTRAL viewer the *browser* loading indicator is never hidden (since we never unblock the "load" event). --- web/app.js | 27 +++++++++++++++++---------- web/base_viewer.js | 16 ++++++++++------ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/web/app.js b/web/app.js index 1356ea627..704ac1b95 100644 --- a/web/app.js +++ b/web/app.js @@ -949,22 +949,22 @@ const PDFViewerApplication = { pdfDocument => { this.load(pdfDocument); }, - exception => { + reason => { if (loadingTask !== this.pdfLoadingTask) { return undefined; // Ignore errors for previously opened PDF files. } let key = "loading_error"; - if (exception instanceof InvalidPDFException) { + if (reason instanceof InvalidPDFException) { key = "invalid_file_error"; - } else if (exception instanceof MissingPDFException) { + } else if (reason instanceof MissingPDFException) { key = "missing_file_error"; - } else if (exception instanceof UnexpectedResponseException) { + } else if (reason instanceof UnexpectedResponseException) { key = "unexpected_response_error"; } return this.l10n.get(key).then(msg => { - this._documentError(msg, { message: exception?.message }); - throw exception; + this._documentError(msg, { message: reason?.message }); + throw reason; }); } ); @@ -1368,11 +1368,18 @@ const PDFViewerApplication = { }); }); - pagesPromise.then(() => { - this._unblockDocumentLoadEvent(); + pagesPromise.then( + () => { + this._unblockDocumentLoadEvent(); - this._initializeAutoPrint(pdfDocument, openActionPromise); - }); + this._initializeAutoPrint(pdfDocument, openActionPromise); + }, + reason => { + this.l10n.get("loading_error").then(msg => { + this._documentError(msg, { message: reason?.message }); + }); + } + ); onePageRendered.then(data => { this.externalServices.reportTelemetry({ diff --git a/web/base_viewer.js b/web/base_viewer.js index 3ea105873..931958ced 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -530,12 +530,14 @@ class BaseViewer { this.eventBus.dispatch("scrollmodechanged", { source: this, mode }); } - this._pagesCapability.promise.then(() => { - this.eventBus.dispatch("pagesloaded", { - source: this, - pagesCount, - }); - }); + this._pagesCapability.promise.then( + () => { + this.eventBus.dispatch("pagesloaded", { source: this, pagesCount }); + }, + () => { + /* Prevent "Uncaught (in promise)"-messages in the console. */ + } + ); this._onBeforeDraw = evt => { const pageView = this._pages[evt.pageNumber - 1]; @@ -680,6 +682,8 @@ class BaseViewer { }) .catch(reason => { console.error("Unable to initialize viewer", reason); + + this._pagesCapability.reject(reason); }); }