Bug 1575058 - Fix assorted bugs with showing errors in the console while replaying, r=loganfsmyth.

Differential Revision: https://phabricator.services.mozilla.com/D42704

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Brian Hackett 2019-08-24 23:54:33 +00:00
Родитель 8a4a4f0f3a
Коммит 8d4c428010
4 изменённых файлов: 122 добавлений и 16 удалений

Просмотреть файл

@ -13,6 +13,7 @@ support-files =
!/devtools/client/debugger/test/mochitest/helpers.js
!/devtools/client/debugger/test/mochitest/helpers/context.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/webconsole/test/browser/head.js
examples/*
[browser_dbg_rr_breakpoints-01.js]
@ -32,6 +33,7 @@ support-files =
[browser_dbg_rr_replay-03.js]
[browser_dbg_rr_console_warp-01.js]
[browser_dbg_rr_console_warp-02.js]
[browser_dbg_rr_console_warp-03.js]
[browser_dbg_rr_logpoint-01.js]
[browser_dbg_rr_logpoint-02.js]
[browser_rr_inspector-01.js]

Просмотреть файл

@ -0,0 +1,49 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable no-undef */
"use strict";
const BrowserTest = {
gTestPath,
ok,
registerCleanupFunction,
waitForExplicitFinish,
BrowserTestUtils,
};
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/webconsole/test/browser/head.js",
BrowserTest
);
// Test evaluating various expressions in the console after time warping.
add_task(async function() {
const dbg = await attachRecordingDebugger("doc_rr_error.html", {
waitForRecording: true,
});
const { toolbox } = dbg;
const console = await toolbox.selectTool("webconsole");
const hud = console.hud;
await warpToMessage(hud, dbg, "Number 5");
BrowserTest.execute(hud, "Error('helo')");
await waitFor(() => findMessage(hud, "helo"));
BrowserTest.execute(
hud,
`
function f() {
throw Error("there");
}
f();
`
);
await BrowserTest.checkMessageStack(hud, "Error: there", [3, 5]);
await shutdownDebugger(dbg);
});

Просмотреть файл

@ -407,7 +407,10 @@ ReplayDebugger.prototype = {
if (!this._objects[data.id]) {
this._addObject(data);
}
this._getObject(data.id)._preview = preview;
this._getObject(data.id)._preview = {
...preview,
enumerableOwnProperties: mapify(preview.enumerableOwnProperties),
};
}
for (const { data, names } of Object.values(pauseData.environments)) {
@ -489,7 +492,7 @@ ReplayDebugger.prototype = {
_getScript(id) {
if (!id) {
return null;
return undefined;
}
const rv = this._scripts[id];
if (rv) {
@ -625,7 +628,10 @@ ReplayDebugger.prototype = {
return { return: this._convertValue(value.return) };
}
if ("throw" in value) {
return { throw: this._convertValue(value.throw) };
return {
throw: this._convertValue(value.throw),
stack: value.stack,
};
}
ThrowError("Unexpected completion value");
return null; // For eslint
@ -1039,6 +1045,11 @@ ReplayDebuggerObject.prototype = {
this._properties = null;
},
toString() {
const id = this._data ? this._data.id : "INVALID";
return `ReplayDebugger.Object #${id}`;
},
get callable() {
return this._data.callable;
},
@ -1096,12 +1107,12 @@ ReplayDebuggerObject.prototype = {
getOwnPropertyNames() {
this._ensureProperties();
return Object.keys(this._properties);
return [...this._properties.keys()];
},
getEnumerableOwnPropertyNamesForPreview() {
if (this._preview) {
return Object.keys(this._preview.enumerableOwnProperties);
if (this._preview && this._preview.enumerableOwnProperties) {
return [...this._preview.enumerableOwnProperties.keys()];
}
return this.getOwnPropertyNames();
},
@ -1121,7 +1132,7 @@ ReplayDebuggerObject.prototype = {
getOwnPropertyDescriptor(name) {
if (this._preview) {
if (this._preview.enumerableOwnProperties) {
const desc = this._preview.enumerableOwnProperties[name];
const desc = this._preview.enumerableOwnProperties.get(name);
if (desc) {
return this._convertPropertyDescriptor(desc);
}
@ -1136,16 +1147,17 @@ ReplayDebuggerObject.prototype = {
}
}
this._ensureProperties();
return this._convertPropertyDescriptor(this._properties[name]);
return this._convertPropertyDescriptor(this._properties.get(name));
},
_ensureProperties() {
if (!this._properties) {
const id = this._data.id;
this._properties = this._dbg._sendRequestAllowDiverge(
const properties = this._dbg._sendRequestAllowDiverge(
{ type: "getObjectProperties", id },
[]
);
this._properties = mapify(properties);
}
},
@ -1226,16 +1238,16 @@ ReplayDebuggerObject.prototype = {
NYI();
},
get errorMessageName() {
NYI();
return this._data.errorMessageName;
},
get errorNotes() {
NYI();
return this._data.errorNotes;
},
get errorLineNumber() {
NYI();
return this._data.errorLineNumber;
},
get errorColumnNumber() {
NYI();
return this._data.errorColumnNumber;
},
get isPromise() {
NYI();
@ -1267,9 +1279,9 @@ ReplayDebugger.Object = ReplayDebuggerObject;
function ReplayDebuggerObjectSnapshot(dbg, data) {
this._dbg = dbg;
this._data = data;
this._properties = Object.create(null);
this._properties = new Map();
data.properties.forEach(({ name, desc }) => {
this._properties[name] = desc;
this._properties.set(name, desc);
});
}
@ -1387,4 +1399,15 @@ function stringify(object) {
return str;
}
function mapify(object) {
if (!object) {
return undefined;
}
const map = new Map();
for (const key of Object.keys(object)) {
map.set(key, object[key]);
}
return map;
}
module.exports = ReplayDebugger;

Просмотреть файл

@ -849,11 +849,31 @@ function convertCompletionValue(value, options) {
return { return: convertValue(value.return, options) };
}
if ("throw" in value) {
return { throw: convertValue(value.throw, options) };
return {
throw: convertValue(value.throw, options),
stack: convertSavedFrameToPlainObject(value.stack),
};
}
throwError("Unexpected completion value");
}
// Make sure that SavedFrame objects can be serialized to JSON.
function convertSavedFrameToPlainObject(frame) {
if (!frame) {
return null;
}
return {
source: frame.source,
sourceId: frame.sourceId,
line: frame.line,
column: frame.column,
functionDisplayName: frame.functionDisplayName,
asyncCause: frame.asyncCause,
parent: convertSavedFrameToPlainObject(frame.parent),
asyncParent: convertSavedFrameToPlainObject(frame.asyncParent),
};
}
// Convert a value we received from the parent.
function convertValueFromParent(value) {
if (isNonNullObject(value)) {
@ -1306,6 +1326,18 @@ function getObjectData(id) {
rv.proxyTarget = convertValue(object.proxyTarget);
rv.proxyHandler = convertValue(object.proxyHandler);
}
if (object.errorMessageName) {
rv.errorMessageName = object.errorMessageName;
}
if (object.errorNotes) {
rv.errorNotes = object.errorNotes;
}
if (object.errorLineNumber) {
rv.errorLineNumber = object.errorLineNumber;
}
if (object.errorColumnNumber) {
rv.errorColumnNumber = object.errorColumnNumber;
}
return rv;
}
if (object instanceof Debugger.Environment) {