Page.Events.Error should throw an proper error

This patch:
- renames Page.Events.Exception in Page.Events.Error
- dispatches an error which has a page stack as its message
This commit is contained in:
Andrey Lushnikov 2017-06-16 11:21:44 -07:00
parent 2066da9ec7
commit 632b90efae
3 changed files with 45 additions and 25 deletions

View File

@ -213,11 +213,12 @@ class Page extends EventEmitter {
return this._userAgent; return this._userAgent;
} }
_handleException(exceptionDetails) { /**
var stack = []; * @param {!Object} exceptionDetails
if (exceptionDetails.stackTrace) */
stack = exceptionDetails.stackTrace.callFrames.map(cf => cf.url); async _handleException(exceptionDetails) {
this.emit(Page.Events.Exception, exceptionDetails.exception.description, stack); var message = await this._getExceptionMessage(exceptionDetails);
this.emit(Page.Events.Error, new Error(message));
} }
_onConsoleAPI(event) { _onConsoleAPI(event) {
@ -330,8 +331,8 @@ class Page extends EventEmitter {
expression: code expression: code
}); });
if (response.exceptionDetails) { if (response.exceptionDetails) {
await throwException(this._client, response.exceptionDetails); var message = await this._getExceptionMessage(response.exceptionDetails);
return; throw new Error('Evaluation failed: ' + message);
} }
var remoteObject = response.result; var remoteObject = response.result;
@ -348,29 +349,38 @@ class Page extends EventEmitter {
objectId: remoteObject.objectId objectId: remoteObject.objectId
}); });
if (response.exceptionDetails) { if (response.exceptionDetails) {
await throwException(this._client, response.exceptionDetails); var message = await this._getExceptionMessage(response.exceptionDetails);
return; throw new Error('Evaluation failed with ' + message);
} }
return response.result.value; return response.result.value;
}
/** /**
* @param {!Object} exceptionDetails * @param {!Object} exceptionDetails
* @return {!Promise} * @return {string}
*/ */
async function throwException(client, exceptionDetails) { async _getExceptionMessage(exceptionDetails) {
var message = '';
var exception = exceptionDetails.exception; var exception = exceptionDetails.exception;
if (!exception) { if (exception) {
throw new Error('Evaluation failed with ' + exceptionDetails.text); var response = await this._client.send('Runtime.callFunctionOn', {
return;
}
var response = await client.send('Runtime.callFunctionOn', {
objectId: exception.objectId, objectId: exception.objectId,
functionDeclaration: 'function() { return this.toString(); }', functionDeclaration: 'function() { return this.message; }',
returnByValue: true, returnByValue: true,
}); });
throw new Error('Evaluation failed with ' + response.result.value); message = response.result.value;
} else {
message = exceptionDetails.text;
} }
if (exceptionDetails.stackTrace) {
for (var callframe of exceptionDetails.stackTrace.callFrames) {
var location = callframe.url + ':' + callframe.lineNumber + ':' + callframe.columnNumber;
var functionName = callframe.functionName || '<anonymous>';
message += `\n at ${functionName} (${location})`;
}
}
return message;
} }
/** /**
@ -583,7 +593,7 @@ function convertPrintParameterToInches(parameter) {
Page.Events = { Page.Events = {
ConsoleMessage: 'consolemessage', ConsoleMessage: 'consolemessage',
Dialog: 'dialog', Dialog: 'dialog',
Exception: 'exception', Error: 'error',
ResourceLoadingFailed: 'resourceloadingfailed', ResourceLoadingFailed: 'resourceloadingfailed',
ResponseReceived: 'responsereceived', ResponseReceived: 'responsereceived',
}; };

View File

@ -64,7 +64,7 @@ class WebPage {
this._pageEvents.on(PageEvents.Confirm, message => this._onConfirm(message)); this._pageEvents.on(PageEvents.Confirm, message => this._onConfirm(message));
this._pageEvents.on(PageEvents.Alert, message => this._onAlert(message)); this._pageEvents.on(PageEvents.Alert, message => this._onAlert(message));
this._pageEvents.on(PageEvents.Dialog, dialog => this._onDialog(dialog)); this._pageEvents.on(PageEvents.Dialog, dialog => this._onDialog(dialog));
this._pageEvents.on(PageEvents.Exception, (exception, stack) => (this._onError || noop).call(null, exception, stack)); this._pageEvents.on(PageEvents.Error, error => (this._onError || noop).call(null, error.message, error.stack));
} }
/** /**

View File

@ -72,7 +72,7 @@ describe('Puppeteer', function() {
error = e; error = e;
} }
expect(error).toBeTruthy(); expect(error).toBeTruthy();
expect(error.message).toContain('ReferenceError'); expect(error.message).toContain('not is not defined');
})); }));
}); });
@ -186,6 +186,16 @@ describe('Puppeteer', function() {
expect(result).toBe('answer!'); expect(result).toBe('answer!');
})); }));
}); });
describe('Page.Events.Error', function() {
it('should fire', function(done) {
page.on('error', error => {
expect(error.message).toContain('Fancy');
done();
});
page.navigate(STATIC_PREFIX + '/error.html');
});
});
}); });
// Since Jasmine doesn't like async functions, they should be wrapped // Since Jasmine doesn't like async functions, they should be wrapped