Skip to content

fix(imap): attach error/close handlers to prevent silent exit on idle drops#29

Open
elcamino666 wants to merge 1 commit into
codefuturist:mainfrom
elcamino666:fix/imap-error-handlers
Open

fix(imap): attach error/close handlers to prevent silent exit on idle drops#29
elcamino666 wants to merge 1 commit into
codefuturist:mainfrom
elcamino666:fix/imap-error-handlers

Conversation

@elcamino666

Copy link
Copy Markdown

Problem

ConnectionManager.getImapClient creates an ImapFlow client without attaching error or close listeners. When the IMAP server drops an idle connection — which most hosted providers do after ~29 minutes (Hostinger in our case) — ImapFlow emits error. With no listener, Node treats it as uncaughtException and exits the process.

Because the client is constructed with logger: false, nothing is written to stderr. From the user's perspective the MCP server simply disappears mid-session and Claude Code / Cursor reports the tools as deferred/disconnected with no trace in the MCP log.

We hit this reproducibly on Hostinger: every session went silent ~30 minutes after the last successful tool call. Log file showed clean tool calls then nothing — no error, no shutdown line.

Fix

Attach error and close handlers before client.connect() so we never miss an event:

  • error: log via mcpLog (catching its promise so the handler itself cannot throw) and drop the cached client.
  • close: drop the cached client.

The next getImapClient() call then reconnects via the existing usable check — exactly the auto-reconnect behaviour the file's docstring already promises.

Impact

  • Healthy connections: no behavior change.
  • Idle drops / network blips: self-heal instead of crashing the process.

Verification

  • npm run build — clean
  • npm run lint — clean
  • npm test — 150/150 pass
  • Patched the same change into a local install; ran a session past the 29-min idle window — connection lazy-reconnected on the next tool call instead of taking the server down.

Open to feedback on log level (warning vs info) or whether the close handler should also log.

Without listeners, an idle IMAP connection that the server later drops
emits an error event with no listener. Node treats that as an
uncaughtException and silently exits the process. Because logger is
false, there is no trace in the MCP log: the server simply disappears
mid-session and the client reports the tools as disconnected with no
obvious cause.

Most hosted providers close IDLE sessions after about 29 minutes
(reproduced against Hostinger), which produced a reliable silent-exit
roughly 30 minutes into a session.

Attach error and close handlers before client.connect:

- Log the error via mcpLog (catching the promise so the handler itself
  cannot throw).
- Drop the cached client so the next getImapClient call reconnects
  through the existing usable check.

No behavior change on healthy connections; idle drops now self-heal
instead of crashing the process.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant