From c8996f654fa8c1c8100e84ba387d0dabb9b0d598 Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Fri, 25 Dec 2015 13:24:19 +0100 Subject: [PATCH] Detect and handle premature worker load error Fall back to a fake worker if the worker fails to load or initialize, e.g. due to a network error, a security error or simply a script error. --- src/display/api.js | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/display/api.js b/src/display/api.js index 6aa315644..4f40c49f8 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -1302,11 +1302,32 @@ var PDFWorker = (function PDFWorkerClosure() { // https://bugzilla.mozilla.org/show_bug.cgi?id=683280 var worker = new Worker(workerSrc); var messageHandler = new MessageHandler('main', 'worker', worker); - messageHandler.on('test', function PDFWorker_test(data) { + var terminateEarly = function() { + worker.removeEventListener('error', onWorkerError); + messageHandler.destroy(); + worker.terminate(); if (this.destroyed) { this._readyCapability.reject(new Error('Worker was destroyed')); - messageHandler.destroy(); - worker.terminate(); + } else { + // Fall back to fake worker if the termination is caused by an + // error (e.g. NetworkError / SecurityError). + this._setupFakeWorker(); + } + }.bind(this); + + var onWorkerError = function(event) { + if (!this._webWorker) { + // Worker failed to initialize due to an error. Clean up and fall + // back to the fake worker. + terminateEarly(); + } + }.bind(this); + worker.addEventListener('error', onWorkerError); + + messageHandler.on('test', function PDFWorker_test(data) { + worker.removeEventListener('error', onWorkerError); + if (this.destroyed) { + terminateEarly(); return; // worker was destroyed } var supportTypedArray = data && data.supportTypedArray; @@ -1333,10 +1354,9 @@ var PDFWorker = (function PDFWorkerClosure() { }); messageHandler.on('ready', function (data) { + worker.removeEventListener('error', onWorkerError); if (this.destroyed) { - this._readyCapability.reject(new Error('Worker was destroyed')); - messageHandler.destroy(); - worker.terminate(); + terminateEarly(); return; // worker was destroyed } try {