1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
/* 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/. */
/**
* The 3 methods here are duplicated from ThreadSafeDevToolsUtils.js
* The ones defined here are used from other sys.mjs files, mostly from the
* NetworkObserver codebase, while the ones remaining in ThreadSafeDevToolsUtils.js
* are used in commonjs modules, including modules which can be loaded in workers.
*
* sys.mjs modules are currently not supported in workers, see Bug 1247687.
*/
/**
* Report that |who| threw an exception, |exception|.
*/
function reportException(who, exception) {
const msg = `${who} threw an exception: ${safeErrorString(exception)}`;
dump(msg + "\n");
if (typeof console !== "undefined" && console && console.error) {
console.error(exception);
}
}
/**
* Given a handler function that may throw, return an infallible handler
* function that calls the fallible handler, and logs any exceptions it
* throws.
*
* @param handler function
* A handler function, which may throw.
* @param aName string
* A name for handler, for use in error messages. If omitted, we use
* handler.name.
*
* (SpiderMonkey does generate good names for anonymous functions, but we
* don't have a way to get at them from JavaScript at the moment.)
*/
function makeInfallible(handler, name = handler.name) {
return function () {
try {
return handler.apply(this, arguments);
} catch (ex) {
let who = "Handler function";
if (name) {
who += " " + name;
}
reportException(who, ex);
return undefined;
}
};
}
/**
* Turn the |error| into a string, without fail.
*
* @param {Error|any} error
*/
function safeErrorString(error) {
try {
let errorString = error.toString();
if (typeof errorString == "string") {
// Attempt to attach a stack to |errorString|. If it throws an error, or
// isn't a string, don't use it.
try {
if (error.stack) {
const stack = error.stack.toString();
if (typeof stack == "string") {
errorString += "\nStack: " + stack;
}
}
} catch (ee) {
// Ignore.
}
// Append additional line and column number information to the output,
// since it might not be part of the stringified error.
if (
typeof error.lineNumber == "number" &&
typeof error.columnNumber == "number"
) {
errorString +=
"Line: " + error.lineNumber + ", column: " + error.columnNumber;
}
return errorString;
}
} catch (ee) {
// Ignore.
}
// We failed to find a good error description, so do the next best thing.
return Object.prototype.toString.call(error);
}
export const DevToolsInfaillibleUtils = {
makeInfallible,
reportException,
safeErrorString,
};
|