js: Add utility to improve error message formatting
Previously, when we formatted SyntaxErrors with toString(), they wouldn't display the file/line/column where the syntax error occurred. This adds a utility function that performs a more comprehensive formatting that displays location information for SyntaxErrors, as well as the .cause property of the error if it is present. This formatting is equivalent to what we do in gjs-console when logging an error. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3041>
This commit is contained in:
parent
5fe6e5c865
commit
a1a320d3d1
@ -19,6 +19,7 @@
|
||||
<file>misc/dateUtils.js</file>
|
||||
<file>misc/dbusUtils.js</file>
|
||||
<file>misc/dependencies.js</file>
|
||||
<file>misc/errorUtils.js</file>
|
||||
<file>misc/extensionUtils.js</file>
|
||||
<file>misc/fileUtils.js</file>
|
||||
<file>misc/gnomeSession.js</file>
|
||||
|
62
js/misc/errorUtils.js
Normal file
62
js/misc/errorUtils.js
Normal file
@ -0,0 +1,62 @@
|
||||
// Common code for displaying errors to the user in various dialogs
|
||||
|
||||
function formatSyntaxErrorLocation(error) {
|
||||
const {fileName = '<unknown>', lineNumber = 0, columnNumber = 0} = error;
|
||||
return ` @ ${fileName}:${lineNumber}:${columnNumber}`;
|
||||
}
|
||||
|
||||
function formatExceptionStack(error) {
|
||||
const {stack} = error;
|
||||
if (!stack)
|
||||
return '\n\n(No stack trace)';
|
||||
|
||||
const indentedStack = stack.split('\n').map(line => ` ${line}`).join('\n');
|
||||
return `\n\nStack trace:\n${indentedStack}`;
|
||||
}
|
||||
|
||||
function formatExceptionWithCause(error, seenCauses) {
|
||||
let fmt = formatExceptionStack(error);
|
||||
|
||||
const {cause} = error;
|
||||
if (!cause)
|
||||
return fmt;
|
||||
|
||||
fmt += `\nCaused by: ${cause}`;
|
||||
|
||||
if (cause !== null && typeof cause === 'object') {
|
||||
if (seenCauses.has(cause))
|
||||
return fmt; // avoid recursion
|
||||
seenCauses.add(cause);
|
||||
|
||||
fmt += formatExceptionWithCause(cause, seenCauses);
|
||||
}
|
||||
|
||||
return fmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a thrown exception into a string, including the stack, taking the
|
||||
* location where a SyntaxError was thrown into account.
|
||||
*
|
||||
* @param {Error} error The error to format
|
||||
* @returns {string} The formatted string
|
||||
*/
|
||||
export function formatError(error) {
|
||||
try {
|
||||
let fmt = `${error}`;
|
||||
if (error === null || typeof error !== 'object')
|
||||
return fmt;
|
||||
|
||||
if (error instanceof SyntaxError) {
|
||||
fmt += formatSyntaxErrorLocation(error);
|
||||
fmt += formatExceptionStack(error);
|
||||
return fmt;
|
||||
}
|
||||
|
||||
const seenCauses = new Set([error]);
|
||||
fmt += formatExceptionWithCause(error, seenCauses);
|
||||
return fmt;
|
||||
} catch (e) {
|
||||
return `(could not display error: ${e})`;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user