mirror of https://github.com/zulip/zulip.git
blueslip: Show popups for thrown non-Error values in development.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
18137709a1
commit
148af2a301
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue