shell hardening: log() guards stdout (EPIPE) + uncaughtException log-and-continue
Exposed by the update drill: a packaged launch whose stdout consumer exits (piped run, launcher) died on its next log line with an uncaught EPIPE dialog. The stdout write is now guarded; the durable channel is userData/logs/main.log. Stray main-process exceptions log and continue - the window + child server are the product.
This commit is contained in:
+20
-1
@@ -80,6 +80,17 @@ if (!app.requestSingleInstanceLock()) {
|
|||||||
|
|
||||||
let serverProcess = null;
|
let serverProcess = null;
|
||||||
|
|
||||||
|
// A GUI shell must never die to a stray exception (EPIPE dialogs, a race
|
||||||
|
// in an event handler): the window + child server are the product, and
|
||||||
|
// anything main-side is recoverable by logging it. Log-and-continue.
|
||||||
|
process.on("uncaughtException", (err) => {
|
||||||
|
try {
|
||||||
|
log(`uncaught: ${err?.stack ?? err}`);
|
||||||
|
} catch {
|
||||||
|
/* nothing left to write to */
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/** A free TCP port (listen(0) → the kernel assigns one). The close→spawn
|
/** A free TCP port (listen(0) → the kernel assigns one). The close→spawn
|
||||||
* race is theoretical; localhost ports are rarely contended, and a failed
|
* race is theoretical; localhost ports are rarely contended, and a failed
|
||||||
* spawn surfaces in the health check with the child's stderr in the log. */
|
* spawn surfaces in the health check with the child's stderr in the log. */
|
||||||
@@ -103,7 +114,15 @@ function freePort() {
|
|||||||
|
|
||||||
function log(line) {
|
function log(line) {
|
||||||
const stamp = new Date().toISOString();
|
const stamp = new Date().toISOString();
|
||||||
console.log(`[lh ${stamp}] ${line}`);
|
// The stdout write is guarded (EPIPE hardening, 2026-10-10): a packaged
|
||||||
|
// app launched with a consumer-owned pipe (a launcher that exits, a
|
||||||
|
// piped run) must not die on its next log line when the pipe breaks.
|
||||||
|
// The file below stays the durable channel.
|
||||||
|
try {
|
||||||
|
console.log(`[lh ${stamp}] ${line}`);
|
||||||
|
} catch {
|
||||||
|
/* stdout gone — userData/logs/main.log still carries it */
|
||||||
|
}
|
||||||
// Belt and braces: also append to userData/logs so a misbehaving child
|
// Belt and braces: also append to userData/logs so a misbehaving child
|
||||||
// can be diagnosed after the window is gone. Best effort only.
|
// can be diagnosed after the window is gone. Best effort only.
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user