hi-sass-frame/src/main/hook/exceptionHook.ts
2024-09-08 23:46:15 +08:00

148 lines
3.8 KiB
TypeScript

import {WebContents, app, dialog} from "electron";
import type {
Details,
RenderProcessGoneDetails,
Event,
BrowserWindow,
} from "electron";
export interface UseProcessExceptionReturn {
/**
* Emitted when the renderer process unexpectedly disappears. This is normally because it was crashed or killed.
* If a listener is not passed in, it will default to following the crash prompt
*
* @see https://www.electronjs.org/docs/latest/api/app#event-render-process-gone
*/
renderProcessGone: (
listener?: (
event: Event,
webContents: WebContents,
details: RenderProcessGoneDetails
) => void
) => void;
/**
* Emitted when the child process unexpectedly disappears. This is normally because it was crashed or killed. It does not include renderer processes.
* If a listener is not passed in, it will default to following the crash prompt
*
* @see https://www.electronjs.org/docs/latest/api/app#event-child-process-gone
*/
childProcessGone: (
window: BrowserWindow,
listener?: (event: Event, details: Details) => void
) => void;
}
export const useProcessException = (): UseProcessExceptionReturn => {
const renderProcessGone = (
listener?: (
event: Event,
webContents: WebContents,
details: RenderProcessGoneDetails
) => void
) => {
app.on("render-process-gone", (event, webContents, details) => {
if (listener) {
listener(event, webContents, details);
return;
}
const message = {
title: "",
buttons: [],
message: "",
};
switch (details.reason) {
case "crashed":
message.title = "警告";
message.buttons = ["确定", "退出"];
message.message = "图形化进程崩溃,是否进行软重启操作?";
break;
case "killed":
message.title = "警告";
message.buttons = ["确定", "退出"];
message.message =
"由于未知原因导致图形化进程被终止,是否进行软重启操作?";
break;
case "oom":
message.title = "警告";
message.buttons = ["确定", "退出"];
message.message = "内存不足,是否软重启释放内存?";
break;
default:
break;
}
dialog
.showMessageBox({
type: "warning",
title: message.title,
buttons: message.buttons,
message: message.message,
noLink: true,
})
.then((res) => {
if (res.response === 0) webContents.reload();
else webContents.close();
});
});
};
const childProcessGone = (
window: BrowserWindow,
listener?: (event: Event, details: Details) => void
) => {
app.on("child-process-gone", (event, details) => {
if (listener) {
listener(event, details);
return;
}
const message = {
title: "",
buttons: [],
message: "",
};
switch (details.type) {
case "GPU":
switch (details.reason) {
case "crashed":
message.title = "警告";
message.buttons = ["确定", "退出"];
message.message = "硬件加速进程已崩溃,是否关闭硬件加速并重启?";
break;
case "killed":
message.title = "警告";
message.buttons = ["确定", "退出"];
message.message =
"硬件加速进程被意外终止,是否关闭硬件加速并重启?";
break;
default:
break;
}
break;
default:
break;
}
dialog
.showMessageBox(window, {
type: "warning",
title: message.title,
buttons: message.buttons,
message: message.message,
noLink: true,
})
.then((res) => {
// 当显卡出现崩溃现象时使用该设置禁用显卡加速模式。
if (res.response === 0) {
if (details.type === "GPU") app.disableHardwareAcceleration();
window.reload();
} else {
window.close();
}
});
});
};
return {
renderProcessGone,
childProcessGone,
};
};