@@ -18,6 +18,49 @@ const path = require("node:path");
1818const { execFile, execFileSync } = require ( "node:child_process" ) ;
1919const { autoUpdater } = require ( "electron-updater" ) ;
2020
21+ // Electron main process can crash with "write EPIPE" if stdout/stderr is a closed pipe
22+ // (common when launched via certain parent processes). Ignore broken-pipe writes so
23+ // transient logging doesn't bring down the app.
24+ const isIgnorablePipeWriteError = ( err ) =>
25+ Boolean ( err ) &&
26+ typeof err === "object" &&
27+ ( err . code === "EPIPE" || err . code === "ERR_STREAM_DESTROYED" || err . code === "ERR_IPC_CHANNEL_CLOSED" ) ;
28+
29+ const patchBrokenPipeWrites = ( stream ) => {
30+ if ( ! stream ) return ;
31+
32+ try {
33+ if ( typeof stream . on === "function" ) {
34+ stream . on ( "error" , ( err ) => {
35+ if ( isIgnorablePipeWriteError ( err ) ) return ;
36+ } ) ;
37+ }
38+ } catch {
39+ // ignore
40+ }
41+
42+ try {
43+ if ( typeof stream . write !== "function" ) return ;
44+ if ( stream . write . __paste_patched ) return ;
45+ const origWrite = stream . write . bind ( stream ) ;
46+ const wrapped = ( ...args ) => {
47+ try {
48+ return origWrite ( ...args ) ;
49+ } catch ( err ) {
50+ if ( isIgnorablePipeWriteError ( err ) ) return false ;
51+ throw err ;
52+ }
53+ } ;
54+ wrapped . __paste_patched = true ;
55+ stream . write = wrapped ;
56+ } catch {
57+ // ignore
58+ }
59+ } ;
60+
61+ patchBrokenPipeWrites ( process . stdout ) ;
62+ patchBrokenPipeWrites ( process . stderr ) ;
63+
2164const isDev = ! app . isPackaged ;
2265const parsePort = ( raw , fallback ) => {
2366 const n = Number . parseInt ( String ( raw ?? "" ) , 10 ) ;
0 commit comments