Griply crashes on MacOS hotspot disconnect

Hi, my Griply crashes on disconnect when using a hotspot. I caught the stack trace by running the app in the terminal.

Here is Claude’s analysis on the fix. Looks easy. Thanks!

What makes the last disconnection different

Look at the timestamps:

every hourly update check before 05:58 actually

succeeded

("Update for version 2.3.0 is not available …"). The

ECONNRESET

/

ETIMEDOUT

blocks scattered between them are stray TLS socket read errors from

TLSWrap.onStreamRead

— keep‑alive sockets being torn down

after

the check completed. electron‑updater's HTTP layer logs those to stderr (that's why they have no

electron‑log prefix) but tolerates them. They never produce a rejected update promise, so they never reach your process‑level handlers. The app survives every time. The 05:58 event is the

only disconnect that coincided with the check actually firing

, and the network was

fully

down at that instant. So instead of a mid‑stream socket reset, Electron's network stack rejected the request at initiation: 05:58:02.824 › Error: Error: net::ERR_INTERNET_DISCONNECTED at SimpleURLLoaderWrapper... (Electron's net module, not Node's TLS) That error type

rejects the

checkForUpdatesAndNotify()

promise

, which the others did not. And that rejection is what kills you.

The actual crash mechanism

Two pieces of your bundled main combine into a footgun:

1.

The update check is called with no

.catch()

(

main-CBHvN0yQ.js:10916

):

const

r =

() =>

{ mainExports.autoUpdater.checkForUpdatesAndNotify(); }; The

autoUpdater.on("error", …)

listener logs

"Update error"

(line 10931) — that's the log line you see — but handling the

event

does

not

stop the returned

promise

from rejecting. So you get an

unhandledRejection

.

2.

Your global handler (

main-CBHvN0yQ.js:29946‑29967

): handleCryptoCrash =

(

r) => {

const

n = r.toString();

if

(n.includes(

"computeSecret"

) || n.includes(

"ERR_CRYPTO_ECDH..."

) || ...) {

// FCM key hot-recovery

return

; }

throw

r;

// <-- line 29964, the crash site in your log

}; process.on(

"uncaughtException"

, handleCryptoCrash); process.on(

"unhandledRejection"

, handleCryptoCrash); This handler exists to hot‑recover corrupted FCM push‑notification keys. For

anything else

it does

throw r

. Throwing from inside an

uncaughtException

/

unhandledRejection

handler is fatal — Node can't re‑catch it (that would loop), so it terminates the process. That's the

throw r

^ trace ending in

Node.js v22.21.1

. So the crash is essentially self‑inflicted: the disconnected‑at‑check‑time scenario is the one path that generates a non‑crypto unhandledRejection, and your handler rethrows it straight into process death.

Why "launched from terminal" mattered

Nothing about terminal launch causes the crash — the mechanism is identical under Finder/production. Launching from the terminal just let you

see

the stderr (

throw r

, the stack,

Node.js v22.21.1

). From Finder the same event would silently quit the app, which is exactly the "mystery crash on hotspot reconnect" you were chasing.

Fixes (in your source, not the bundle)

1.

Catch the update promise

— the

error

event already handles it, so the rejection is pure noise:

const

r =

() =>

{ autoUpdater.checkForUpdatesAndNotify().catch(

() =>

{}); }; 2.

Don't rethrow unrelated errors in

handleCryptoCrash

.

Re‑throwing in these handlers is what converts a survivable error into a hard exit. Log and swallow (or at least don't register it for

unhandledRejection

):

const

handleCryptoCrash =

(

r) => {

if

(isFcmCryptoError(r)) {

/* recover */

return

; }

console

.error(

"Unhandled:"

, r);

// log, don't throw r

}; Either fix alone stops this crash; #1 is the targeted fix, #2 closes the broader class of "any unhandled rejection kills Griply." I'd do both.

Please authenticate to join the conversation.

Upvoters
Status

In Review

Board

🐞 Bugs

Date

2 months ago

Subscribe to post

Get notified by email when there are changes.