Compare commits

...
Author SHA1 Message Date
Sonarly Claude CodeandClaude Opus 4.6 3d31c1f081 fix: handle IMAP connection drop errors to prevent unhandled rejections
When the IMAP server closes the connection, imapflow's emitError() emits
an 'error' event on the client. Without a listener, Node.js throws an
uncaught exception, which disrupts the async flow and causes subsequent
pending request rejections (via setImmediate in close()) to become
unhandled promise rejections reported to Sentry.

1. Add an 'error' event listener on the ImapFlow client to gracefully
   handle asynchronous connection errors (socket errors, TLS failures).
2. Add message-based fallback detection in isImapNetworkError for
   "Connection not available" errors, ensuring they are classified as
   temporary network errors even if the error code property is missing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:38:09 +00:00
2 changed files with 25 additions and 10 deletions
@@ -94,6 +94,12 @@ export class ImapClientProvider {
greetingTimeout: ImapClientProvider.GREETING_TIMEOUT_MS,
});
client.on('error', (error: Error) => {
this.logger.error(
`IMAP client error for ${connectedAccount.handle}: ${error.message}`,
);
});
try {
await client.connect();
@@ -27,24 +27,33 @@ const NODEJS_NETWORK_ERROR_CODES = [
MessageNetworkExceptionCode.EHOSTUNREACH,
];
const IMAPFLOW_CONNECTION_ERROR_MESSAGES = ['Connection not available'];
export const isImapNetworkError = (error: Error): boolean => {
const errorWithCode = error as { code?: string };
if (!isDefined(errorWithCode.code)) {
return false;
}
if (isDefined(errorWithCode.code)) {
if (IMAPFLOW_TIMEOUT_ERROR_CODES.includes(errorWithCode.code)) {
return true;
}
if (IMAPFLOW_TIMEOUT_ERROR_CODES.includes(errorWithCode.code)) {
return true;
}
if (IMAPFLOW_CONNECTION_ERROR_CODES.includes(errorWithCode.code)) {
return true;
}
if (IMAPFLOW_CONNECTION_ERROR_CODES.includes(errorWithCode.code)) {
return true;
if (
NODEJS_NETWORK_ERROR_CODES.includes(
errorWithCode.code as MessageNetworkExceptionCode,
)
) {
return true;
}
}
if (
NODEJS_NETWORK_ERROR_CODES.includes(
errorWithCode.code as MessageNetworkExceptionCode,
error.message &&
IMAPFLOW_CONNECTION_ERROR_MESSAGES.some((msg) =>
error.message.includes(msg),
)
) {
return true;