forked from mirrors/gecko-dev
130 lines
3.6 KiB
JavaScript
130 lines
3.6 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
// Test that stack traces are shown when primitive values are thrown instead of
|
|
// error objects.
|
|
|
|
"use strict";
|
|
|
|
const TEST_URI = `data:text/html,<!DOCTYPE html><meta charset=utf8>Test uncaught exception`;
|
|
|
|
add_task(async function () {
|
|
const hud = await openNewTabAndConsole(TEST_URI);
|
|
|
|
await checkThrowingWithStack(hud, `"tomato"`, "Uncaught tomato");
|
|
await checkThrowingWithStack(hud, `""`, "Uncaught <empty string>");
|
|
await checkThrowingWithStack(hud, `42`, "Uncaught 42");
|
|
await checkThrowingWithStack(hud, `0`, "Uncaught 0");
|
|
await checkThrowingWithStack(hud, `null`, "Uncaught null");
|
|
await checkThrowingWithStack(hud, `undefined`, "Uncaught undefined");
|
|
await checkThrowingWithStack(hud, `false`, "Uncaught false");
|
|
|
|
await checkThrowingWithStack(
|
|
hud,
|
|
`new Error("watermelon")`,
|
|
"Uncaught Error: watermelon"
|
|
);
|
|
|
|
await checkThrowingWithStack(
|
|
hud,
|
|
`(err = new Error("lettuce"), err.name = "VegetableError", err)`,
|
|
"Uncaught VegetableError: lettuce"
|
|
);
|
|
|
|
await checkThrowingWithStack(
|
|
hud,
|
|
`{ fav: "eggplant" }`,
|
|
`Uncaught Object { fav: "eggplant" }`
|
|
);
|
|
|
|
info("Check custom error with name and message getters");
|
|
// register the class
|
|
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () {
|
|
const script = content.document.createElement("script");
|
|
script.append(
|
|
content.document.createTextNode(
|
|
`
|
|
class CustomError extends Error {
|
|
get name() {
|
|
return "CustomErrorName";
|
|
}
|
|
|
|
get message() {
|
|
return "custom-error-message";
|
|
}
|
|
}`.trim()
|
|
)
|
|
);
|
|
content.document.body.append(script);
|
|
});
|
|
|
|
await checkThrowingWithStack(
|
|
hud,
|
|
`new CustomError()`,
|
|
"Uncaught CustomErrorName: custom-error-message",
|
|
// Additional frames: the stacktrace contains the CustomError call
|
|
[1]
|
|
);
|
|
info("Check that object in errors can be expanded");
|
|
const rejectedObjectMessage = findErrorMessage(hud, "eggplant");
|
|
const oi = rejectedObjectMessage.querySelector(".tree");
|
|
ok(true, "The object was rendered in an ObjectInspector");
|
|
|
|
info("Expanding the object");
|
|
const onOiExpanded = waitFor(() => {
|
|
return oi.querySelectorAll(".node").length === 3;
|
|
});
|
|
oi.querySelector(".arrow").click();
|
|
await onOiExpanded;
|
|
|
|
ok(
|
|
oi.querySelector(".arrow").classList.contains("expanded"),
|
|
"Object expanded"
|
|
);
|
|
|
|
// The object inspector now looks like:
|
|
// Object { fav: "eggplant" }
|
|
// | fav: "eggplant"
|
|
// | <prototype>: Object { ... }
|
|
|
|
const oiNodes = oi.querySelectorAll(".node");
|
|
is(oiNodes.length, 3, "There is the expected number of nodes in the tree");
|
|
|
|
ok(oiNodes[0].textContent.includes(`Object { fav: "eggplant" }`));
|
|
ok(oiNodes[1].textContent.includes(`fav: "eggplant"`));
|
|
ok(oiNodes[2].textContent.includes(`<prototype>: Object { \u2026 }`));
|
|
});
|
|
|
|
async function checkThrowingWithStack(
|
|
hud,
|
|
expression,
|
|
expectedMessage,
|
|
additionalFrameLines = []
|
|
) {
|
|
await SpecialPowers.spawn(
|
|
gBrowser.selectedBrowser,
|
|
[expression],
|
|
function (expr) {
|
|
const script = content.document.createElement("script");
|
|
script.append(
|
|
content.document.createTextNode(`
|
|
a = () => {throw ${expr}};
|
|
b = () => a();
|
|
c = () => b();
|
|
d = () => c();
|
|
d();
|
|
`)
|
|
);
|
|
content.document.body.append(script);
|
|
script.remove();
|
|
}
|
|
);
|
|
return checkMessageStack(hud, expectedMessage, [
|
|
...additionalFrameLines,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
]);
|
|
}
|