Backed out changeset 162bc74a2c75 (bug 1644186) for perma failures on browser_webconsole_stubs_page_error.js. CLOSED TREE

This commit is contained in:
Razvan Maries 2020-07-09 15:20:24 +03:00
parent e23631e029
commit 3ed03d134b
13 changed files with 69 additions and 709 deletions

View File

@ -36,10 +36,7 @@ add_task(async function() {
});
async function waitForMessageAndViewSource(hud, message) {
const msg = await waitFor(
() => findMessage(hud, message),
`Message "${message}" wasn't found`
);
const msg = await waitFor(() => findMessage(hud, message));
ok(msg, `Message found: "${message}"`);
const locationNode = msg.querySelector(

View File

@ -82,6 +82,7 @@ rawPackets.set(`ReferenceError: asdf is not defined`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -163,6 +164,7 @@ rawPackets.set(`SyntaxError: redeclaration of let a`, {
}
],
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -248,6 +250,7 @@ rawPackets.set(`TypeError longString message`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -333,6 +336,7 @@ rawPackets.set(`throw string with URL`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": "“https://evil.com/?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa“ is evil and “https://not-so-evil.com/?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa“ is not good either",
@ -390,6 +394,7 @@ rawPackets.set(`throw ""`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": "",
@ -447,6 +452,7 @@ rawPackets.set(`throw "tomato"`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": "tomato",
@ -504,6 +510,7 @@ rawPackets.set(`throw false`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": false,
@ -561,6 +568,7 @@ rawPackets.set(`throw 0`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": 0,
@ -618,6 +626,7 @@ rawPackets.set(`throw null`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -677,6 +686,7 @@ rawPackets.set(`throw undefined`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -736,6 +746,7 @@ rawPackets.set(`throw Symbol`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -797,6 +808,7 @@ rawPackets.set(`throw Object`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -880,6 +892,7 @@ rawPackets.set(`throw Error Object`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -957,6 +970,7 @@ rawPackets.set(`throw Error Object with custom name`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": false,
"isForwardedFromContentProcess": false,
"exception": {
@ -1034,6 +1048,7 @@ rawPackets.set(`Promise reject ""`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": "",
@ -1091,6 +1106,7 @@ rawPackets.set(`Promise reject "tomato"`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": "tomato",
@ -1148,6 +1164,7 @@ rawPackets.set(`Promise reject false`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": false,
@ -1205,6 +1222,7 @@ rawPackets.set(`Promise reject 0`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": 0,
@ -1262,6 +1280,7 @@ rawPackets.set(`Promise reject null`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": {
@ -1321,6 +1340,7 @@ rawPackets.set(`Promise reject undefined`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": {
@ -1380,6 +1400,7 @@ rawPackets.set(`Promise reject Symbol`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": {
@ -1441,6 +1462,7 @@ rawPackets.set(`Promise reject Object`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": {
@ -1524,6 +1546,7 @@ rawPackets.set(`Promise reject Error Object`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": {
@ -1601,6 +1624,7 @@ rawPackets.set(`Promise reject Error Object with custom name`, {
],
"notes": null,
"chromeContext": false,
"cssSelectors": "",
"isPromiseRejection": true,
"isForwardedFromContentProcess": false,
"exception": {

View File

@ -88,16 +88,13 @@ exports.WatcherActor = protocol.ActorClassWithSpec(watcherSpec, {
false
);
const hasBrowserElement = !!this.browserElement;
return {
actor: this.actorID,
traits: {
// FF77+ supports frames in Watcher actor
frame: true,
resources: {
// FF79+ supports console and platform messages, FF80+ supports error messages,
// but this isn't enabled yet.
// FF79+ supports console messages and platform messages, but this isn't enabled yet.
// We will implement a few other resources before enabling it in bug 1642295.
// This is to prevent having to handle backward compat if we have to change Watcher
// Actor API while implementing other resources.
@ -105,9 +102,7 @@ exports.WatcherActor = protocol.ActorClassWithSpec(watcherSpec, {
// content process targets yet. Bug 1620248 should help supporting them and enable
// this more broadly.
[Resources.TYPES.CONSOLE_MESSAGE]:
enableServerWatcher && hasBrowserElement,
[Resources.TYPES.ERROR_MESSAGE]:
enableServerWatcher && hasBrowserElement,
enableServerWatcher && !!this.browserElement,
[Resources.TYPES.PLATFORM_MESSAGE]: enableServerWatcher,
},
},

View File

@ -1,275 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Ci, Cu } = require("chrome");
const Services = require("Services");
const ChromeUtils = require("ChromeUtils");
const { DevToolsServer } = require("devtools/server/devtools-server");
const ErrorDocs = require("devtools/server/actors/errordocs");
const {
createStringGrip,
makeDebuggeeValue,
createValueGripForTarget,
} = require("devtools/server/actors/object/utils");
const {
getActorIdForInternalSourceId,
} = require("devtools/server/actors/utils/dbg-source");
const {
TYPES: { ERROR_MESSAGE },
} = require("devtools/server/actors/resources/index");
class ErrorMessageWatcher {
/**
* Start watching for all error messages related to a given Target Actor.
* This will notify about existing console messages, but also the one created in future.
*
* @param TargetActor targetActor
* The target actor from which we should observe console messages
* @param Object options
* Dictionary object with following attributes:
* - onAvailable: mandatory function
* This will be called for each resource.
*/
constructor(targetActor, { onAvailable }) {
// The following code expects the ThreadActor to be instantiated, via:
// buildPageErrorResource > TabSources.getActorIdForInternalSourceId
// The Thread Actor is instantiated via Target.attach, but we should
// probably review this and only instantiate the actor instead of attaching the target.
targetActor.attach();
// Create the consoleListener.
const listener = {
QueryInterface: ChromeUtils.generateQI(["nsIConsoleListener"]),
observe(message) {
if (!shouldHandleMessage(targetActor, message)) {
return;
}
onAvailable([buildPageErrorResource(targetActor, message)]);
},
};
// Retrieve the cached messages just before registering the listener, so we don't get
// duplicated messages.
const cachedMessages = Services.console.getMessageArray() || [];
Services.console.registerListener(listener);
this.listener = listener;
// Remove unwanted cache messages and send an array of resources.
const messages = [];
for (const message of cachedMessages) {
if (!shouldHandleMessage(targetActor, message)) {
continue;
}
messages.push(buildPageErrorResource(targetActor, message));
}
onAvailable(messages);
}
/**
* Stop watching for console messages.
*/
destroy() {
if (this.listener) {
Services.console.unregisterListener(this.listener);
}
}
}
module.exports = ErrorMessageWatcher;
/**
* Returns true if the message is considered an error message, and as a result, should
* be sent to the client.
*
* @param {nsIConsoleMessage|nsIScriptError} message
*/
function shouldHandleMessage(targetActor, message) {
// The listener we use can be called either with a nsIConsoleMessage or a nsIScriptError.
// In this file, we only want to handle nsIScriptError.
if (
// We only care about nsIScriptError
!(message instanceof Ci.nsIScriptError) ||
!isCategoryAllowed(targetActor, message.category) ||
// Block any error that was triggered by eager evaluation
message.sourceName === "debugger eager eval code" ||
// In Process targets don't include messages from private window
(isProcessTarget(targetActor) && message.isFromPrivateWindow)
) {
return false;
}
// Process targets listen for everything
if (isProcessTarget(targetActor)) {
return true;
}
if (!message.innerWindowID) {
return false;
}
const { window } = targetActor.window;
const win = window?.WindowGlobalChild?.getByInnerWindowId(
message.innerWindowID
);
return targetActor.browserId === win?.browsingContext?.browserId;
}
const PLATFORM_SPECIFIC_CATEGORIES = [
"XPConnect JavaScript",
"component javascript",
"chrome javascript",
"chrome registration",
];
/**
* Check if the given message category is allowed to be tracked or not.
* We ignore chrome-originating errors as we only care about content.
*
* @param string category
* The message category you want to check.
* @return boolean
* True if the category is allowed to be logged, false otherwise.
*/
function isCategoryAllowed(targetActor, category) {
// CSS Parser errors will be handled by the CSSMessageWatcher.
if (!category || category === "CSS Parser") {
return false;
}
// We listen for everything on Process targets
if (isProcessTarget(targetActor)) {
return true;
}
// For non-process targets, we filter-out platform-specific errors.
return !PLATFORM_SPECIFIC_CATEGORIES.includes(category);
}
function isProcessTarget(targetActor) {
const { typeName } = targetActor;
return (
typeName === "parentProcessTarget" || typeName === "contentProcessTarget"
);
}
/**
* Prepare an nsIScriptError to be sent to the client.
*
* @param nsIScriptError error
* The page error we need to send to the client.
* @return object
* The object you can send to the remote client.
*/
function buildPageErrorResource(targetActor, error) {
const stack = prepareStackForRemote(targetActor, error.stack);
let lineText = error.sourceLine;
if (lineText && lineText.length > DevToolsServer.LONG_STRING_INITIAL_LENGTH) {
lineText = lineText.substr(0, DevToolsServer.LONG_STRING_INITIAL_LENGTH);
}
let notesArray = null;
const notes = error.notes;
if (notes?.length) {
notesArray = [];
for (let i = 0, len = notes.length; i < len; i++) {
const note = notes.queryElementAt(i, Ci.nsIScriptErrorNote);
notesArray.push({
messageBody: createStringGrip(targetActor, note.errorMessage),
frame: {
source: note.sourceName,
sourceId: getActorIdForInternalSourceId(targetActor, note.sourceId),
line: note.lineNumber,
column: note.columnNumber,
},
});
}
}
// If there is no location information in the error but we have a stack,
// fill in the location with the first frame on the stack.
let { sourceName, sourceId, lineNumber, columnNumber } = error;
if (!sourceName && !sourceId && !lineNumber && !columnNumber && stack) {
sourceName = stack[0].filename;
sourceId = stack[0].sourceId;
lineNumber = stack[0].lineNumber;
columnNumber = stack[0].columnNumber;
}
const pageError = {
errorMessage: createStringGrip(targetActor, error.errorMessage),
errorMessageName: error.errorMessageName,
exceptionDocURL: ErrorDocs.GetURL(error),
sourceName,
sourceId: getActorIdForInternalSourceId(targetActor, sourceId),
lineText,
lineNumber,
columnNumber,
category: error.category,
innerWindowID: error.innerWindowID,
timeStamp: error.timeStamp,
warning: !!(error.flags & error.warningFlag),
error: !(error.flags & (error.warningFlag | error.infoFlag)),
info: !!(error.flags & error.infoFlag),
private: error.isFromPrivateWindow,
stacktrace: stack,
notes: notesArray,
chromeContext: error.isFromChromeContext,
isPromiseRejection: error.isPromiseRejection,
isForwardedFromContentProcess: error.isForwardedFromContentProcess,
};
// If the pageError does have an exception object, we want to return the grip for it,
// but only if we do manage to get the grip, as we're checking the property on the
// client to render things differently.
if (error.hasException) {
try {
const obj = makeDebuggeeValue(targetActor, error.exception);
if (obj?.class !== "DeadObject") {
pageError.exception = createValueGripForTarget(targetActor, obj);
pageError.hasException = true;
}
} catch (e) {}
}
return {
pageError,
resourceType: ERROR_MESSAGE,
};
}
/**
* Prepare a SavedFrame stack to be sent to the client.
*
* @param SavedFrame errorStack
* Stack for an error we need to send to the client.
* @return object
* The object you can send to the remote client.
*/
function prepareStackForRemote(targetActor, errorStack) {
// Convert stack objects to the JSON attributes expected by client code
// Bug 1348885: If the global from which this error came from has been
// nuked, stack is going to be a dead wrapper.
if (!errorStack || (Cu && Cu.isDeadWrapper(errorStack))) {
return null;
}
const stack = [];
let s = errorStack;
while (s) {
stack.push({
filename: s.source,
sourceId: getActorIdForInternalSourceId(targetActor, s.sourceId),
lineNumber: s.line,
columnNumber: s.column,
functionName: s.functionDisplayName,
asyncCause: s.asyncCause ? s.asyncCause : undefined,
});
s = s.parent || s.asyncParent;
}
return stack;
}

View File

@ -6,7 +6,6 @@
const TYPES = {
CONSOLE_MESSAGE: "console-message",
ERROR_MESSAGE: "error-message",
PLATFORM_MESSAGE: "platform-message",
};
exports.TYPES = TYPES;
@ -25,9 +24,6 @@ const Resources = {
[TYPES.CONSOLE_MESSAGE]: {
path: "devtools/server/actors/resources/console-messages",
},
[TYPES.ERROR_MESSAGE]: {
path: "devtools/server/actors/resources/error-messages",
},
[TYPES.PLATFORM_MESSAGE]: {
path: "devtools/server/actors/resources/platform-messages",
},

View File

@ -6,7 +6,6 @@
DevToolsModules(
'console-messages.js',
'error-messages.js',
'index.js',
'platform-messages.js',
)

View File

@ -17,7 +17,7 @@ const { LongStringActor } = require("devtools/server/actors/string");
class PlatformMessageWatcher {
/**
* Start watching for all platform messages related to a given Target Actor.
* Start watching for all console messages related to a given Target Actor.
* This will notify about existing console messages, but also the one created in future.
*
* @param TargetActor targetActor

View File

@ -503,6 +503,4 @@ const LegacyListeners = {
const ResourceTransformers = {
[ResourceWatcher.TYPES
.CONSOLE_MESSAGE]: require("devtools/shared/resources/transformers/console-messages"),
[ResourceWatcher.TYPES
.ERROR_MESSAGE]: require("devtools/shared/resources/transformers/error-messages"),
};

View File

@ -154,43 +154,26 @@ function logExistingMessages(browser) {
content.console.warn("foobarBaz-warn", content.document.body);
});
}
const NUMBER_REGEX = /^\d+$/;
const defaultStackFrames = [
{
filename: "resource://testing-common/content-task.js",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
},
{
filename: "resource://testing-common/content-task.js",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
asyncCause: "MessageListener.receiveMessage",
},
];
const expectedExistingConsoleCalls = [
{
level: "log",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: ["foobarBaz-log", { type: "undefined" }],
},
{
level: "info",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: ["foobarBaz-info", { type: "null" }],
},
{
level: "warn",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: ["foobarBaz-warn", { type: "object", actor: /[a-z]/ }],
},
];
@ -201,7 +184,7 @@ const expectedRuntimeConsoleCalls = [
level: "log",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: ["foobarBaz-log", { type: "undefined" }],
},
{
@ -220,41 +203,40 @@ const expectedRuntimeConsoleCalls = [
level: "info",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: ["foobarBaz-info", { type: "null" }],
},
{
level: "warn",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: ["foobarBaz-warn", { type: "object", actor: /[a-z]/ }],
},
{
level: "debug",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: [{ type: "null" }],
},
{
level: "trace",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
stacktrace: [
{
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
},
...defaultStackFrames,
],
},
{
level: "dir",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: [
{
type: "object",
@ -272,7 +254,7 @@ const expectedRuntimeConsoleCalls = [
level: "log",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: [
"foo",
{
@ -290,7 +272,7 @@ const expectedRuntimeConsoleCalls = [
level: "log",
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: [
{
type: "object",
@ -303,7 +285,7 @@ const expectedRuntimeConsoleCalls = [
level: "error",
filename: EXPECTED_FILENAME,
functionName: "fromAsmJS",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
arguments: ["foobarBaz-asmjs-error", { type: "undefined" }],
stacktrace: [
@ -323,7 +305,6 @@ const expectedRuntimeConsoleCalls = [
filename: EXPECTED_FILENAME,
functionName: EXPECTED_FUNCTION_NAME,
},
...defaultStackFrames,
],
},
];

View File

@ -24,18 +24,6 @@ add_task(async function() {
// which forces the emission of RDP requests we aren't correctly waiting for.
await pushPref("dom.ipc.processPrelaunch.enabled", false);
info("Test error messages legacy listener");
await testErrorMessagesResources();
await testErrorMessagesResourcesWithIgnoreExistingResources();
info("Test error messages server listener");
await pushPref("devtools.testing.enableServerWatcherSupport", true);
await testErrorMessagesResources();
await testErrorMessagesResourcesWithIgnoreExistingResources();
await pushPref("devtools.testing.enableServerWatcherSupport", false);
});
async function testErrorMessagesResources() {
// Open a test tab
const tab = await addTab(TEST_URI);
@ -105,10 +93,15 @@ async function testErrorMessagesResources() {
Services.console.reset();
targetList.stopListening();
await client.close();
}
});
async function testErrorMessagesResourcesWithIgnoreExistingResources() {
add_task(async function() {
info("Test ignoreExistingResources option for ERROR_MESSAGE");
// Disable the preloaded process as it creates processes intermittently
// which forces the emission of RDP requests we aren't correctly waiting for.
await pushPref("dom.ipc.processPrelaunch.enabled", false);
const tab = await addTab(TEST_URI);
const {
@ -149,7 +142,7 @@ async function testErrorMessagesResourcesWithIgnoreExistingResources() {
Services.console.reset();
await targetList.stopListening();
await client.close();
}
});
/**
* Triggers all the errors in the content page.
@ -181,31 +174,6 @@ async function triggerErrors(tab) {
}
const noUncaughtException = Symbol();
const NUMBER_REGEX = /^\d+$/;
const mdnUrl = path =>
`https://developer.mozilla.org/${path}?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default`;
const defaultStackFrames = [
{
filename: /resource:\/\/testing-common\/content-task.js/,
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
functionName: "frameScript",
},
{
filename: "resource://testing-common/content-task.js",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
functionName: null,
},
{
filename: "resource://testing-common/content-task.js",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
functionName: null,
asyncCause: "MessageListener.receiveMessage",
},
];
const expectedPageErrors = new Map([
[
@ -215,33 +183,9 @@ const expectedPageErrors = new Map([
errorMessageName: undefined,
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl(
"docs/Web/JavaScript/Reference/Errors/Not_a_function"
),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 10,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -251,31 +195,9 @@ const expectedPageErrors = new Map([
errorMessageName: "JSMSG_BAD_RADIX",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl("docs/Web/JavaScript/Reference/Errors/Bad_radix"),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 6,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -285,31 +207,9 @@ const expectedPageErrors = new Map([
errorMessageName: "JSMSG_READ_ONLY",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl("docs/Web/JavaScript/Reference/Errors/Read-only"),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 23,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -319,33 +219,9 @@ const expectedPageErrors = new Map([
errorMessageName: "JSMSG_BAD_ARRAY_LENGTH",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl(
"docs/Web/JavaScript/Reference/Errors/Invalid_array_length"
),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 2,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -355,40 +231,9 @@ const expectedPageErrors = new Map([
errorMessageName: "JSMSG_NEGATIVE_REPETITION_COUNT",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl(
"docs/Web/JavaScript/Reference/Errors/Negative_repetition_count"
),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: "self-hosted",
sourceId: null,
lineNumber: NUMBER_REGEX,
columnNumber: 1,
functionName: "repeat",
},
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 7,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -398,40 +243,9 @@ const expectedPageErrors = new Map([
errorMessageName: "JSMSG_RESULTING_STRING_TOO_LARGE",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl(
"docs/Web/JavaScript/Reference/Errors/Resulting_string_too_large"
),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: "self-hosted",
sourceId: null,
lineNumber: NUMBER_REGEX,
columnNumber: 1,
functionName: "repeat",
},
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 5,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -441,33 +255,9 @@ const expectedPageErrors = new Map([
errorMessageName: "JSMSG_PRECISION_RANGE",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl(
"docs/Web/JavaScript/Reference/Errors/Precision_range"
),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 9,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -477,24 +267,9 @@ const expectedPageErrors = new Map([
errorMessageName: "JSMSG_STMT_AFTER_RETURN",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: false,
warning: true,
info: false,
sourceId: null,
lineText: "function a() { return; 1 + 1; }",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl(
"docs/Web/JavaScript/Reference/Errors/Stmt_after_return"
),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: null,
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -504,23 +279,9 @@ const expectedPageErrors = new Map([
errorMessageName: "JSMSG_REDECLARED_VAR",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "{let a, a;}",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl(
"docs/Web/JavaScript/Reference/Errors/Redeclared_parameter"
),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: defaultStackFrames,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
notes: [
{
messageBody: /Previously declared at line/,
@ -541,31 +302,9 @@ const expectedPageErrors = new Map([
errorMessageName: "",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl("docs/Web/JavaScript/Reference/Errors/Read-only"),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 13,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
@ -575,79 +314,24 @@ const expectedPageErrors = new Map([
errorMessageName: "MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl("docs/Web/JavaScript/Reference/Errors/Read-only"),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 1,
columnNumber: 33,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: false,
isForwardedFromContentProcess: false,
},
],
[
`
function promiseThrow() {
var error2 = new TypeError("abc");
error2.name = "MyPromiseError";
error2.message = "here2";
return Promise.reject(error2);
}
promiseThrow()`,
`var error2 = new TypeError("abc");
error2.name = "MyPromiseError";
error2.message = "here2";
Promise.reject(error2)`,
{
errorMessage: /MyPromiseError: here2/,
errorMessageName: "",
sourceName: /test_page_errors/,
category: "content javascript",
timeStamp: NUMBER_REGEX,
timeStamp: /^\d+$/,
error: true,
warning: false,
info: false,
sourceId: null,
lineText: "",
lineNumber: NUMBER_REGEX,
columnNumber: NUMBER_REGEX,
exceptionDocURL: mdnUrl("docs/Web/JavaScript/Reference/Errors/Read-only"),
innerWindowID: NUMBER_REGEX,
private: false,
stacktrace: [
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 6,
columnNumber: 24,
functionName: "promiseThrow",
},
{
filename: /test_page_errors\.html/,
sourceId: null,
lineNumber: 8,
columnNumber: 7,
functionName: null,
},
...defaultStackFrames,
],
notes: null,
chromeContext: false,
isPromiseRejection: true,
isForwardedFromContentProcess: false,
[noUncaughtException]: true,
},
],

View File

@ -69,11 +69,11 @@ function checkObject(object, expected) {
function checkValue(name, value, expected) {
if (expected === null) {
is(value, null, `'${name}' is null`);
ok(!value, "'" + name + "' is null");
} else if (value === undefined) {
is(value, undefined, `'${name}' is undefined`);
ok(false, "'" + name + "' is undefined");
} else if (value === null) {
is(value, expected, `'${name}' has expected value`);
ok(false, "'" + name + "' is null");
} else if (
typeof expected == "string" ||
typeof expected == "number" ||
@ -84,14 +84,7 @@ function checkValue(name, value, expected) {
ok(expected.test(value), name + ": " + expected + " matched " + value);
} else if (Array.isArray(expected)) {
info("checking array for property '" + name + "'");
ok(Array.isArray(value), `property '${name}' is an array`);
is(value.length, expected.length, "Array has expected length");
if (value.length !== expected.length) {
is(JSON.stringify(value, null, 2), JSON.stringify(expected, null, 2));
} else {
checkObject(value, expected);
}
checkObject(value, expected);
} else if (typeof expected == "object") {
info("checking object for property '" + name + "'");
checkObject(value, expected);

View File

@ -1,31 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// eslint-disable-next-line mozilla/reject-some-requires
loader.lazyRequireGetter(
this,
"getAdHocFrontOrPrimitiveGrip",
"devtools/client/fronts/object",
true
);
module.exports = function({ resource, targetFront }) {
if (resource?.pageError?.errorMessage) {
resource.pageError.errorMessage = getAdHocFrontOrPrimitiveGrip(
resource.pageError.errorMessage,
targetFront
);
}
if (resource?.pageError?.exception) {
resource.pageError.exception = getAdHocFrontOrPrimitiveGrip(
resource.pageError.exception,
targetFront
);
}
return resource;
};

View File

@ -3,6 +3,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'console-messages.js',
'error-messages.js',
'console-messages.js'
)