Merge pull request #5275 from Snuffleupagus/exception-propagation

Fix the exception propagation when rejecting workerReadyCapability
This commit is contained in:
Yury Delendik 2014-09-16 10:05:34 -05:00
commit ffb613bbac
6 changed files with 124 additions and 84 deletions

View File

@ -146,6 +146,7 @@ loading_error_indicator=Error
loading_error=An error occurred while loading the PDF. loading_error=An error occurred while loading the PDF.
invalid_file_error=Invalid or corrupted PDF file. invalid_file_error=Invalid or corrupted PDF file.
missing_file_error=Missing PDF file. missing_file_error=Missing PDF file.
unexpected_response_error=Unexpected server response.
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip. # LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
# "{{type}}" will be replaced with an annotation type from a list defined in # "{{type}}" will be replaced with an annotation type from a list defined in

View File

@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* globals error, globalScope, InvalidPDFException, info, /* globals PDFJS, createPromiseCapability, LocalPdfManager, NetworkPdfManager,
MissingPDFException, PasswordException, PDFJS, Promise, NetworkManager, isInt, RANGE_CHUNK_SIZE, MissingPDFException,
UnknownErrorException, NetworkManager, LocalPdfManager, UnexpectedResponseException, PasswordException, Promise,
NetworkPdfManager, XRefParseException, createPromiseCapability, PasswordResponses, InvalidPDFException, UnknownErrorException,
isInt, PasswordResponses, MessageHandler, Ref, RANGE_CHUNK_SIZE */ XRefParseException, Ref, info, globalScope, error, MessageHandler */
'use strict'; 'use strict';
@ -141,14 +141,16 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
}, },
onError: function onError(status) { onError: function onError(status) {
var exception;
if (status === 404) { if (status === 404) {
var exception = new MissingPDFException('Missing PDF "' + exception = new MissingPDFException('Missing PDF "' +
source.url + '".'); source.url + '".');
handler.send('MissingPDF', { exception: exception }); handler.send('MissingPDF', exception);
} else { } else {
handler.send('DocError', 'Unexpected server response (' + exception = new UnexpectedResponseException(
status + ') while retrieving PDF "' + 'Unexpected server response (' + status +
source.url + '".'); ') while retrieving PDF "' + source.url + '".', status);
handler.send('UnexpectedResponse', exception);
} }
}, },
@ -200,26 +202,19 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
var onFailure = function(e) { var onFailure = function(e) {
if (e instanceof PasswordException) { if (e instanceof PasswordException) {
if (e.code === PasswordResponses.NEED_PASSWORD) { if (e.code === PasswordResponses.NEED_PASSWORD) {
handler.send('NeedPassword', { handler.send('NeedPassword', e);
exception: e
});
} else if (e.code === PasswordResponses.INCORRECT_PASSWORD) { } else if (e.code === PasswordResponses.INCORRECT_PASSWORD) {
handler.send('IncorrectPassword', { handler.send('IncorrectPassword', e);
exception: e
});
} }
} else if (e instanceof InvalidPDFException) { } else if (e instanceof InvalidPDFException) {
handler.send('InvalidPDF', { handler.send('InvalidPDF', e);
exception: e
});
} else if (e instanceof MissingPDFException) { } else if (e instanceof MissingPDFException) {
handler.send('MissingPDF', { handler.send('MissingPDF', e);
exception: e } else if (e instanceof UnexpectedResponseException) {
}); handler.send('UnexpectedResponse', e);
} else { } else {
handler.send('UnknownError', { handler.send('UnknownError',
exception: new UnknownErrorException(e.message, e.toString()) new UnknownErrorException(e.message, e.toString()));
});
} }
}; };

View File

@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* globals CanvasGraphics, combineUrl, createScratchCanvas, error, /* globals PDFJS, isArrayBuffer, error, combineUrl, createPromiseCapability,
FontLoader, globalScope, info, isArrayBuffer, loadJpegStream, StatTimer, globalScope, MessageHandler, info, FontLoader, Util, warn,
MessageHandler, PDFJS, Promise, StatTimer, warn, Promise, PasswordResponses, PasswordException, InvalidPDFException,
PasswordResponses, Util, loadScript, createPromiseCapability, MissingPDFException, UnknownErrorException, FontFace, loadJpegStream,
FontFace */ createScratchCanvas, CanvasGraphics, UnexpectedResponseException */
'use strict'; 'use strict';
@ -865,36 +865,46 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.workerReadyCapability.resolve(pdfDocument); this.workerReadyCapability.resolve(pdfDocument);
}, this); }, this);
messageHandler.on('NeedPassword', function transportPassword(data) { messageHandler.on('NeedPassword',
function transportNeedPassword(exception) {
if (this.passwordCallback) { if (this.passwordCallback) {
return this.passwordCallback(updatePassword, return this.passwordCallback(updatePassword,
PasswordResponses.NEED_PASSWORD); PasswordResponses.NEED_PASSWORD);
} }
this.workerReadyCapability.reject(data.exception.message, this.workerReadyCapability.reject(
data.exception); new PasswordException(exception.message, exception.code));
}, this); }, this);
messageHandler.on('IncorrectPassword', function transportBadPass(data) { messageHandler.on('IncorrectPassword',
function transportIncorrectPassword(exception) {
if (this.passwordCallback) { if (this.passwordCallback) {
return this.passwordCallback(updatePassword, return this.passwordCallback(updatePassword,
PasswordResponses.INCORRECT_PASSWORD); PasswordResponses.INCORRECT_PASSWORD);
} }
this.workerReadyCapability.reject(data.exception.message, this.workerReadyCapability.reject(
data.exception); new PasswordException(exception.message, exception.code));
}, this); }, this);
messageHandler.on('InvalidPDF', function transportInvalidPDF(data) { messageHandler.on('InvalidPDF', function transportInvalidPDF(exception) {
this.workerReadyCapability.reject(data.exception.name, data.exception); this.workerReadyCapability.reject(
new InvalidPDFException(exception.message));
}, this); }, this);
messageHandler.on('MissingPDF', function transportMissingPDF(data) { messageHandler.on('MissingPDF', function transportMissingPDF(exception) {
this.workerReadyCapability.reject(data.exception.message, this.workerReadyCapability.reject(
data.exception); new MissingPDFException(exception.message));
}, this); }, this);
messageHandler.on('UnknownError', function transportUnknownError(data) { messageHandler.on('UnexpectedResponse',
this.workerReadyCapability.reject(data.exception.message, function transportUnexpectedResponse(exception) {
data.exception); this.workerReadyCapability.reject(
new UnexpectedResponseException(exception.message, exception.status));
}, this);
messageHandler.on('UnknownError',
function transportUnknownError(exception) {
this.workerReadyCapability.reject(
new UnknownErrorException(exception.message, exception.details));
}, this); }, this);
messageHandler.on('DataLoaded', function transportPage(data) { messageHandler.on('DataLoaded', function transportPage(data) {
@ -990,10 +1000,6 @@ var WorkerTransport = (function WorkerTransportClosure() {
} }
}, this); }, this);
messageHandler.on('DocError', function transportDocError(data) {
this.workerReadyCapability.reject(data);
}, this);
messageHandler.on('PageError', function transportError(data) { messageHandler.on('PageError', function transportError(data) {
var page = this.pageCache[data.pageNum - 1]; var page = this.pageCache[data.pageNum - 1];
var intentState = page.intentStates[data.intent]; var intentState = page.intentStates[data.intent];

View File

@ -342,6 +342,7 @@ var PasswordException = (function PasswordExceptionClosure() {
return PasswordException; return PasswordException;
})(); })();
PDFJS.PasswordException = PasswordException;
var UnknownErrorException = (function UnknownErrorExceptionClosure() { var UnknownErrorException = (function UnknownErrorExceptionClosure() {
function UnknownErrorException(msg, details) { function UnknownErrorException(msg, details) {
@ -355,6 +356,7 @@ var UnknownErrorException = (function UnknownErrorExceptionClosure() {
return UnknownErrorException; return UnknownErrorException;
})(); })();
PDFJS.UnknownErrorException = UnknownErrorException;
var InvalidPDFException = (function InvalidPDFExceptionClosure() { var InvalidPDFException = (function InvalidPDFExceptionClosure() {
function InvalidPDFException(msg) { function InvalidPDFException(msg) {
@ -367,6 +369,7 @@ var InvalidPDFException = (function InvalidPDFExceptionClosure() {
return InvalidPDFException; return InvalidPDFException;
})(); })();
PDFJS.InvalidPDFException = InvalidPDFException;
var MissingPDFException = (function MissingPDFExceptionClosure() { var MissingPDFException = (function MissingPDFExceptionClosure() {
function MissingPDFException(msg) { function MissingPDFException(msg) {
@ -379,6 +382,22 @@ var MissingPDFException = (function MissingPDFExceptionClosure() {
return MissingPDFException; return MissingPDFException;
})(); })();
PDFJS.MissingPDFException = MissingPDFException;
var UnexpectedResponseException =
(function UnexpectedResponseExceptionClosure() {
function UnexpectedResponseException(msg, status) {
this.name = 'UnexpectedResponseException';
this.message = msg;
this.status = status;
}
UnexpectedResponseException.prototype = new Error();
UnexpectedResponseException.constructor = UnexpectedResponseException;
return UnexpectedResponseException;
})();
PDFJS.UnexpectedResponseException = UnexpectedResponseException;
var NotImplementedException = (function NotImplementedExceptionClosure() { var NotImplementedException = (function NotImplementedExceptionClosure() {
function NotImplementedException(msg) { function NotImplementedException(msg) {

View File

@ -1,14 +1,14 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* globals PDFJS, expect, it, describe, Promise, combineUrl, waitsFor, /* globals PDFJS, expect, it, describe, Promise, combineUrl, waitsFor,
isArray */ isArray, MissingPDFException */
'use strict'; 'use strict';
describe('api', function() { describe('api', function() {
// TODO run with worker enabled // TODO run with worker enabled
var basicApiUrl = combineUrl(window.location.href, '../pdfs/basicapi.pdf'); var basicApiUrl = combineUrl(window.location.href, '../pdfs/basicapi.pdf');
function waitsForPromise(promise, successCallback) { function waitsForPromiseResolved(promise, successCallback) {
var data; var data;
promise.then(function(val) { promise.then(function(val) {
data = val; data = val;
@ -22,11 +22,25 @@ describe('api', function() {
return data !== undefined; return data !== undefined;
}, 20000); }, 20000);
} }
function waitsForPromiseRejected(promise, failureCallback) {
var data;
promise.then(function(val) {
// Shouldn't get here.
expect(false).toEqual(true);
},
function(error) {
data = error;
failureCallback(data);
});
waitsFor(function() {
return data !== undefined;
}, 20000);
}
describe('PDFJS', function() { describe('PDFJS', function() {
describe('getDocument', function() { describe('getDocument', function() {
it('creates pdf doc from URL', function() { it('creates pdf doc from URL', function() {
var promise = PDFJS.getDocument(basicApiUrl); var promise = PDFJS.getDocument(basicApiUrl);
waitsForPromise(promise, function(data) { waitsForPromiseResolved(promise, function(data) {
expect(true).toEqual(true); expect(true).toEqual(true);
}); });
}); });
@ -61,16 +75,24 @@ describe('api', function() {
expect(typedArrayPdf.length).toEqual(105779); expect(typedArrayPdf.length).toEqual(105779);
var promise = PDFJS.getDocument(typedArrayPdf); var promise = PDFJS.getDocument(typedArrayPdf);
waitsForPromise(promise, function(data) { waitsForPromiseResolved(promise, function(data) {
expect(true).toEqual(true); expect(true).toEqual(true);
}); });
}); });
it('creates pdf doc from non-existent URL', function() {
var nonExistentUrl = combineUrl(window.location.href,
'../pdfs/non-existent.pdf');
var promise = PDFJS.getDocument(nonExistentUrl);
waitsForPromiseRejected(promise, function(error) {
expect(error instanceof MissingPDFException).toEqual(true);
});
});
}); });
}); });
describe('PDFDocument', function() { describe('PDFDocument', function() {
var promise = PDFJS.getDocument(basicApiUrl); var promise = PDFJS.getDocument(basicApiUrl);
var doc; var doc;
waitsForPromise(promise, function(data) { waitsForPromiseResolved(promise, function(data) {
doc = data; doc = data;
}); });
it('gets number of pages', function() { it('gets number of pages', function() {
@ -81,7 +103,7 @@ describe('api', function() {
}); });
it('gets page', function() { it('gets page', function() {
var promise = doc.getPage(1); var promise = doc.getPage(1);
waitsForPromise(promise, function(data) { waitsForPromiseResolved(promise, function(data) {
expect(true).toEqual(true); expect(true).toEqual(true);
}); });
}); });
@ -89,32 +111,32 @@ describe('api', function() {
// reference to second page // reference to second page
var ref = {num: 17, gen: 0}; var ref = {num: 17, gen: 0};
var promise = doc.getPageIndex(ref); var promise = doc.getPageIndex(ref);
waitsForPromise(promise, function(pageIndex) { waitsForPromiseResolved(promise, function(pageIndex) {
expect(pageIndex).toEqual(1); expect(pageIndex).toEqual(1);
}); });
}); });
it('gets destinations', function() { it('gets destinations', function() {
var promise = doc.getDestinations(); var promise = doc.getDestinations();
waitsForPromise(promise, function(data) { waitsForPromiseResolved(promise, function(data) {
expect(data).toEqual({ chapter1: [{ gen: 0, num: 17 }, { name: 'XYZ' }, expect(data).toEqual({ chapter1: [{ gen: 0, num: 17 }, { name: 'XYZ' },
0, 841.89, null] }); 0, 841.89, null] });
}); });
}); });
it('gets attachments', function() { it('gets attachments', function() {
var promise = doc.getAttachments(); var promise = doc.getAttachments();
waitsForPromise(promise, function (data) { waitsForPromiseResolved(promise, function (data) {
expect(data).toEqual(null); expect(data).toEqual(null);
}); });
}); });
it('gets javascript', function() { it('gets javascript', function() {
var promise = doc.getJavaScript(); var promise = doc.getJavaScript();
waitsForPromise(promise, function (data) { waitsForPromiseResolved(promise, function (data) {
expect(data).toEqual([]); expect(data).toEqual([]);
}); });
}); });
it('gets outline', function() { it('gets outline', function() {
var promise = doc.getOutline(); var promise = doc.getOutline();
waitsForPromise(promise, function(outline) { waitsForPromiseResolved(promise, function(outline) {
// Two top level entries. // Two top level entries.
expect(outline.length).toEqual(2); expect(outline.length).toEqual(2);
// Make sure some basic attributes are set. // Make sure some basic attributes are set.
@ -125,26 +147,26 @@ describe('api', function() {
}); });
it('gets metadata', function() { it('gets metadata', function() {
var promise = doc.getMetadata(); var promise = doc.getMetadata();
waitsForPromise(promise, function(metadata) { waitsForPromiseResolved(promise, function(metadata) {
expect(metadata.info['Title']).toEqual('Basic API Test'); expect(metadata.info['Title']).toEqual('Basic API Test');
expect(metadata.metadata.get('dc:title')).toEqual('Basic API Test'); expect(metadata.metadata.get('dc:title')).toEqual('Basic API Test');
}); });
}); });
it('gets data', function() { it('gets data', function() {
var promise = doc.getData(); var promise = doc.getData();
waitsForPromise(promise, function (data) { waitsForPromiseResolved(promise, function (data) {
expect(true).toEqual(true); expect(true).toEqual(true);
}); });
}); });
it('gets filesize in bytes', function() { it('gets filesize in bytes', function() {
var promise = doc.getDownloadInfo(); var promise = doc.getDownloadInfo();
waitsForPromise(promise, function (data) { waitsForPromiseResolved(promise, function (data) {
expect(data.length).toEqual(105779); expect(data.length).toEqual(105779);
}); });
}); });
it('gets stats', function() { it('gets stats', function() {
var promise = doc.getStats(); var promise = doc.getStats();
waitsForPromise(promise, function (stats) { waitsForPromiseResolved(promise, function (stats) {
expect(isArray(stats.streamTypes)).toEqual(true); expect(isArray(stats.streamTypes)).toEqual(true);
expect(isArray(stats.fontTypes)).toEqual(true); expect(isArray(stats.fontTypes)).toEqual(true);
}); });
@ -161,7 +183,7 @@ describe('api', function() {
}); });
}); });
var page; var page;
waitsForPromise(promise, function(data) { waitsForPromiseResolved(promise, function(data) {
page = data; page = data;
}); });
it('gets page number', function () { it('gets page number', function () {
@ -187,13 +209,13 @@ describe('api', function() {
}); });
it('gets annotations', function () { it('gets annotations', function () {
var promise = page.getAnnotations(); var promise = page.getAnnotations();
waitsForPromise(promise, function (data) { waitsForPromiseResolved(promise, function (data) {
expect(data.length).toEqual(4); expect(data.length).toEqual(4);
}); });
}); });
it('gets text content', function () { it('gets text content', function () {
var promise = page.getTextContent(); var promise = page.getTextContent();
waitsForPromise(promise, function (data) { waitsForPromiseResolved(promise, function (data) {
expect(!!data.items).toEqual(true); expect(!!data.items).toEqual(true);
expect(data.items.length).toEqual(7); expect(data.items.length).toEqual(7);
expect(!!data.styles).toEqual(true); expect(!!data.styles).toEqual(true);
@ -201,7 +223,7 @@ describe('api', function() {
}); });
it('gets operator list', function() { it('gets operator list', function() {
var promise = page.getOperatorList(); var promise = page.getOperatorList();
waitsForPromise(promise, function (oplist) { waitsForPromiseResolved(promise, function (oplist) {
expect(!!oplist.fnArray).toEqual(true); expect(!!oplist.fnArray).toEqual(true);
expect(!!oplist.argsArray).toEqual(true); expect(!!oplist.argsArray).toEqual(true);
expect(oplist.lastChunk).toEqual(true); expect(oplist.lastChunk).toEqual(true);

View File

@ -677,30 +677,27 @@ var PDFView = {
self.load(pdfDocument, scale); self.load(pdfDocument, scale);
self.loading = false; self.loading = false;
}, },
function getDocumentError(message, exception) { function getDocumentError(exception) {
var message = exception && exception.message;
var loadingErrorMessage = mozL10n.get('loading_error', null, var loadingErrorMessage = mozL10n.get('loading_error', null,
'An error occurred while loading the PDF.'); 'An error occurred while loading the PDF.');
if (exception && exception.name === 'InvalidPDFException') { if (exception instanceof PDFJS.InvalidPDFException) {
// change error message also for other builds // change error message also for other builds
loadingErrorMessage = mozL10n.get('invalid_file_error', null, loadingErrorMessage = mozL10n.get('invalid_file_error', null,
'Invalid or corrupted PDF file.'); 'Invalid or corrupted PDF file.');
//#if B2G } else if (exception instanceof PDFJS.MissingPDFException) {
// window.alert(loadingErrorMessage);
// return window.close();
//#endif
}
if (exception && exception.name === 'MissingPDFException') {
// special message for missing PDF's // special message for missing PDF's
loadingErrorMessage = mozL10n.get('missing_file_error', null, loadingErrorMessage = mozL10n.get('missing_file_error', null,
'Missing PDF file.'); 'Missing PDF file.');
} else if (exception instanceof PDFJS.UnexpectedResponseException) {
//#if B2G loadingErrorMessage = mozL10n.get('unexpected_response_error', null,
// window.alert(loadingErrorMessage); 'Unexpected server response.');
// return window.close();
//#endif
} }
//#if B2G
// window.alert(loadingErrorMessage);
// return window.close();
//#endif
var moreInfo = { var moreInfo = {
message: message message: message