fix(desktop): improve renderer recovery prompt

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
J
2026-06-12 14:14:20 +08:00
parent c510515da7
commit 71768dda5c
2 changed files with 44 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
import { installRendererRecoveryHandlers } from "./renderer-recovery";
import { createElectronReloadPrompt, installRendererRecoveryHandlers } from "./renderer-recovery";
type Handler = (...args: unknown[]) => void;
@@ -109,4 +109,30 @@ describe("installRendererRecoveryHandlers", () => {
expect(showReloadPrompt).not.toHaveBeenCalled();
expect(fixture.reload).not.toHaveBeenCalled();
});
it("shows actionable recovery guidance before diagnostic details", async () => {
let detail = "";
const showMessageBox = vi.fn(
async (options: { title: string; message: string; detail: string }) => {
detail = options.detail;
return { response: 1 };
},
);
const showReloadPrompt = createElectronReloadPrompt(showMessageBox);
await showReloadPrompt({ kind: "unresponsive", context: {} });
expect(showMessageBox).toHaveBeenCalledWith(
expect.objectContaining({
title: "Multica needs to reload",
message: "The desktop window has been stuck for a few seconds.",
detail: expect.stringContaining(
"Click Reload to refresh this window and keep using Multica.",
),
}),
);
expect(detail).toContain("what you were doing right before this message appeared");
expect(detail).toContain("Activity Monitor sample");
expect(detail).toContain("Diagnostic details:\nkind: unresponsive\ncontext: {}");
});
});

View File

@@ -109,18 +109,30 @@ function isRecoverableRendererExit(details: unknown) {
function rendererRecoveryMessage(kind: ReloadPromptPayload["kind"]) {
switch (kind) {
case "render-process-gone":
return "The desktop renderer process stopped responding or crashed.";
return "The desktop window stopped unexpectedly.";
case "preload-error":
return "The desktop preload script failed before the app could start.";
return "The desktop window could not finish starting.";
case "unresponsive":
return "The desktop window is not responding.";
return "The desktop window has been stuck for a few seconds.";
}
}
function rendererRecoveryDetail(payload: ReloadPromptPayload) {
const guidance = [
"Click Reload to refresh this window and keep using Multica.",
"If this keeps happening, please tell us what you were doing right before this message appeared and whether Reload recovered the window.",
];
if (payload.kind === "unresponsive") {
guidance.push(
"For macOS reports, an Activity Monitor sample of the Multica Helper (Renderer) process helps us find what blocked the app.",
);
}
return [
"Reloading is the safest recovery path for this window.",
...guidance,
"",
"Diagnostic details:",
`kind: ${payload.kind}`,
`context: ${JSON.stringify(payload.context)}`,
].join("\n");
@@ -132,4 +144,4 @@ function defaultDevLog(tag: string, ...args: unknown[]) {
function formatError(error: unknown) {
return error instanceof Error ? (error.stack ?? error.message) : String(error);
}
}