blueslip: Show popups for thrown non-Error values in development.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2024-06-24 13:12:13 -07:00 committed by Tim Abbott
parent 18137709a1
commit 148af2a301
3 changed files with 40 additions and 27 deletions

View File

@ -111,7 +111,7 @@ export function error(msg: string, more_info?: object | undefined, original_erro
if (DEVELOPMENT) {
$(window).on("error", (event: JQuery.TriggeredEvent) => {
const {originalEvent} = event;
if (originalEvent instanceof ErrorEvent && originalEvent.error instanceof Error) {
if (originalEvent instanceof ErrorEvent) {
void display_stacktrace(originalEvent.error);
}
});

View File

@ -109,41 +109,54 @@ async function get_context(location: StackFrame): Promise<NumberedLine[] | undef
}));
}
export async function display_stacktrace(ex: Error): Promise<void> {
export async function display_stacktrace(ex: unknown): Promise<void> {
const errors = [];
while (true) {
const stackframes: CleanStackFrame[] = await Promise.all(
ErrorStackParser.parse(ex).map(async (location: StackFrame) => {
try {
location = await stack_trace_gps.getMappedLocation(location);
} catch {
// Use unmapped location
}
return {
full_path: location.getFileName(),
show_path: clean_path(location.getFileName()),
line_number: location.getLineNumber(),
function_name: clean_function_name(location.getFunctionName()),
context: await get_context(location),
};
}),
);
do {
if (!(ex instanceof Error)) {
const prototype: unknown = Object.getPrototypeOf(ex);
errors.push({
name:
typeof prototype === "object" &&
prototype !== null &&
"constructor" in prototype
? `thrown ${prototype.constructor.name}`
: "thrown",
message: String(ex),
stackframes: [],
});
break;
}
const stackframes: CleanStackFrame[] =
ex instanceof Error
? await Promise.all(
ErrorStackParser.parse(ex).map(async (location: StackFrame) => {
try {
location = await stack_trace_gps.getMappedLocation(location);
} catch {
// Use unmapped location
}
return {
full_path: location.getFileName(),
show_path: clean_path(location.getFileName()),
line_number: location.getLineNumber(),
function_name: clean_function_name(location.getFunctionName()),
context: await get_context(location),
};
}),
)
: [];
let more_info: string | undefined;
if (ex instanceof BlueslipError) {
more_info = JSON.stringify(ex.more_info, null, 4);
}
errors.push({
name: ex.name,
message: exception_msg(ex),
more_info,
stackframes,
});
if (ex.cause !== undefined && ex.cause instanceof Error) {
ex = ex.cause;
} else {
break;
}
}
ex = ex.cause;
} while (ex !== undefined);
const $alert = $("<div>").addClass("stacktrace").html(render_blueslip_stacktrace({errors}));
$(".alert-box").append($alert);

View File

@ -3,7 +3,7 @@
<div class="warning-symbol">
<i class="fa fa-exclamation-triangle"></i>
</div>
<div class="message"><strong>Error:</strong> {{ message }}</div>
<div class="message">{{#unless @first}}caused by {{/unless}}<strong>{{name}}:</strong> {{ message }}</div>
{{#if @first}}
<div class="exit"></div>
{{/if}}