mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(page): add name property to pageerror event (#5970)
This commit is contained in:
parent
7dccfd4227
commit
8ca58e344e
@ -36,6 +36,7 @@ export function parseError(error: SerializedError): Error {
|
|||||||
}
|
}
|
||||||
const e = new Error(error.error.message);
|
const e = new Error(error.error.message);
|
||||||
e.stack = error.error.stack || '';
|
e.stack = error.error.stack || '';
|
||||||
|
e.name = error.error.name;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import fs from 'fs';
|
|||||||
import * as util from 'util';
|
import * as util from 'util';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { mkdirIfNeeded } from '../../utils/utils';
|
import { mkdirIfNeeded } from '../../utils/utils';
|
||||||
|
import { splitErrorMessage } from '../../utils/stackTrace';
|
||||||
|
|
||||||
export function getExceptionMessage(exceptionDetails: Protocol.Runtime.ExceptionDetails): string {
|
export function getExceptionMessage(exceptionDetails: Protocol.Runtime.ExceptionDetails): string {
|
||||||
if (exceptionDetails.exception)
|
if (exceptionDetails.exception)
|
||||||
@ -74,18 +75,18 @@ export function exceptionToError(exceptionDetails: Protocol.Runtime.ExceptionDet
|
|||||||
const messageWithStack = getExceptionMessage(exceptionDetails);
|
const messageWithStack = getExceptionMessage(exceptionDetails);
|
||||||
const lines = messageWithStack.split('\n');
|
const lines = messageWithStack.split('\n');
|
||||||
const firstStackTraceLine = lines.findIndex(line => line.startsWith(' at'));
|
const firstStackTraceLine = lines.findIndex(line => line.startsWith(' at'));
|
||||||
let message = '';
|
let messageWithName = '';
|
||||||
let stack = '';
|
let stack = '';
|
||||||
if (firstStackTraceLine === -1) {
|
if (firstStackTraceLine === -1) {
|
||||||
message = messageWithStack;
|
messageWithName = messageWithStack;
|
||||||
} else {
|
} else {
|
||||||
message = lines.slice(0, firstStackTraceLine).join('\n');
|
messageWithName = lines.slice(0, firstStackTraceLine).join('\n');
|
||||||
stack = messageWithStack;
|
stack = messageWithStack;
|
||||||
}
|
}
|
||||||
const match = message.match(/^[a-zA-Z0-0_]*Error: (.*)$/);
|
const {name, message} = splitErrorMessage(messageWithName);
|
||||||
if (match)
|
|
||||||
message = match[1];
|
|
||||||
const err = new Error(message);
|
const err = new Error(message);
|
||||||
err.stack = stack;
|
err.stack = stack;
|
||||||
|
err.name = name;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './ffInput';
|
|||||||
import { FFNetworkManager } from './ffNetworkManager';
|
import { FFNetworkManager } from './ffNetworkManager';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
import { Progress } from '../progress';
|
import { Progress } from '../progress';
|
||||||
|
import { splitErrorMessage } from '../../utils/stackTrace';
|
||||||
|
|
||||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||||
|
|
||||||
@ -221,9 +222,11 @@ export class FFPage implements PageDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onUncaughtError(params: Protocol.Page.uncaughtErrorPayload) {
|
_onUncaughtError(params: Protocol.Page.uncaughtErrorPayload) {
|
||||||
const message = params.message.startsWith('Error: ') ? params.message.substring(7) : params.message;
|
const {name, message} = splitErrorMessage(params.message);
|
||||||
|
|
||||||
const error = new Error(message);
|
const error = new Error(message);
|
||||||
error.stack = params.stack;
|
error.stack = params.stack;
|
||||||
|
error.name = name;
|
||||||
this._page.emit(Page.Events.PageError, error);
|
this._page.emit(Page.Events.PageError, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
import * as jpeg from 'jpeg-js';
|
import * as jpeg from 'jpeg-js';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import * as png from 'pngjs';
|
import * as png from 'pngjs';
|
||||||
|
import { splitErrorMessage } from '../../utils/stackTrace';
|
||||||
import { assert, createGuid, debugAssert, headersArrayToObject, headersObjectToArray } from '../../utils/utils';
|
import { assert, createGuid, debugAssert, headersArrayToObject, headersObjectToArray } from '../../utils/utils';
|
||||||
import * as accessibility from '../accessibility';
|
import * as accessibility from '../accessibility';
|
||||||
import * as dialog from '../dialog';
|
import * as dialog from '../dialog';
|
||||||
@ -490,7 +491,7 @@ export class WKPage implements PageDelegate {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (level === 'error' && source === 'javascript') {
|
if (level === 'error' && source === 'javascript') {
|
||||||
const message = text.startsWith('Error: ') ? text.substring(7) : text;
|
const {name, message} = splitErrorMessage(text);
|
||||||
const error = new Error(message);
|
const error = new Error(message);
|
||||||
if (event.message.stackTrace) {
|
if (event.message.stackTrace) {
|
||||||
error.stack = event.message.stackTrace.map(callFrame => {
|
error.stack = event.message.stackTrace.map(callFrame => {
|
||||||
@ -499,6 +500,7 @@ export class WKPage implements PageDelegate {
|
|||||||
} else {
|
} else {
|
||||||
error.stack = '';
|
error.stack = '';
|
||||||
}
|
}
|
||||||
|
error.name = name;
|
||||||
this._page.emit(Page.Events.PageError, error);
|
this._page.emit(Page.Events.PageError, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -69,3 +69,11 @@ export function captureStackTrace(): { stack: string, frames: StackFrame[] } {
|
|||||||
}
|
}
|
||||||
return { stack, frames };
|
return { stack, frames };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function splitErrorMessage(message: string): { name: string, message: string } {
|
||||||
|
const separationIdx = message.indexOf(':');
|
||||||
|
return {
|
||||||
|
name: separationIdx !== -1 ? message.slice(0, separationIdx) : '',
|
||||||
|
message: separationIdx !== -1 && separationIdx + 2 <= message.length ? message.substring(separationIdx + 2) : message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -41,7 +41,37 @@ it('should contain sourceURL', async ({page, server, isWebKit}) => {
|
|||||||
expect(error.stack).toContain('myscript.js');
|
expect(error.stack).toContain('myscript.js');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle odd values', async ({page, isFirefox}) => {
|
it('should contain the Error.name property', async ({ page }) => {
|
||||||
|
const [error] = await Promise.all([
|
||||||
|
page.waitForEvent('pageerror'),
|
||||||
|
page.evaluate(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const error = new Error('my-message');
|
||||||
|
error.name = 'my-name';
|
||||||
|
throw error;
|
||||||
|
}, 0);
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
expect(error.name).toBe('my-name');
|
||||||
|
expect(error.message).toBe('my-message');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support an empty Error.name property', async ({ page }) => {
|
||||||
|
const [error] = await Promise.all([
|
||||||
|
page.waitForEvent('pageerror'),
|
||||||
|
page.evaluate(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const error = new Error('my-message');
|
||||||
|
error.name = '';
|
||||||
|
throw error;
|
||||||
|
}, 0);
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
expect(error.name).toBe('');
|
||||||
|
expect(error.message).toBe('my-message');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle odd values', async ({page}) => {
|
||||||
const cases = [
|
const cases = [
|
||||||
[null, 'null'],
|
[null, 'null'],
|
||||||
[undefined, 'undefined'],
|
[undefined, 'undefined'],
|
||||||
@ -53,14 +83,11 @@ it('should handle odd values', async ({page, isFirefox}) => {
|
|||||||
page.waitForEvent('pageerror'),
|
page.waitForEvent('pageerror'),
|
||||||
page.evaluate(value => setTimeout(() => { throw value; }, 0), value),
|
page.evaluate(value => setTimeout(() => { throw value; }, 0), value),
|
||||||
]);
|
]);
|
||||||
expect(error.message).toBe(isFirefox ? 'uncaught exception: ' + message : message);
|
expect(error.message).toBe(message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle object', async ({page, isChromium, isFirefox}) => {
|
it('should handle object', async ({page, isChromium}) => {
|
||||||
it.fixme(isFirefox);
|
|
||||||
|
|
||||||
// Firefox just does not report this error.
|
|
||||||
const [error] = await Promise.all([
|
const [error] = await Promise.all([
|
||||||
page.waitForEvent('pageerror'),
|
page.waitForEvent('pageerror'),
|
||||||
page.evaluate(() => setTimeout(() => { throw {}; }, 0)),
|
page.evaluate(() => setTimeout(() => { throw {}; }, 0)),
|
||||||
@ -69,10 +96,7 @@ it('should handle object', async ({page, isChromium, isFirefox}) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle window', async ({page, isChromium, isFirefox, isElectron}) => {
|
it('should handle window', async ({page, isChromium, isFirefox, isElectron}) => {
|
||||||
it.fixme(isFirefox);
|
|
||||||
it.skip(isElectron);
|
it.skip(isElectron);
|
||||||
|
|
||||||
// Firefox just does not report this error.
|
|
||||||
const [error] = await Promise.all([
|
const [error] = await Promise.all([
|
||||||
page.waitForEvent('pageerror'),
|
page.waitForEvent('pageerror'),
|
||||||
page.evaluate(() => setTimeout(() => { throw window; }, 0)),
|
page.evaluate(() => setTimeout(() => { throw window; }, 0)),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user