@bobfrankston/mailx-imap 0.1.31 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +20 -3
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -3368,7 +3368,12 @@ export class ImapManager extends EventEmitter {
3368
3368
  // this exact case: `.sending-rmf39-63196` sat in the queue
3369
3369
  // for 7+ hours because PID 63196 was now an unrelated Node.
3370
3370
  // (c) it's our PID — never sweep our own claim.
3371
- const STALE_CLAIM_MS = 3600_000;
3371
+ // 5 minutes: SMTP transactions complete in seconds; 5m of
3372
+ // claim with no progress means the worker is wedged or PID
3373
+ // got recycled. Earlier 1h was a band-aid that left Bob's
3374
+ // outbox stuck for hours when an SMTP wedge crashed the
3375
+ // worker mid-flight.
3376
+ const STALE_CLAIM_MS = 5 * 60_000;
3372
3377
  const myPid = process.pid;
3373
3378
  for (const dir of [outboxDir, queuedDir]) {
3374
3379
  if (!fs.existsSync(dir))
@@ -3470,11 +3475,23 @@ export class ImapManager extends EventEmitter {
3470
3475
  // file is visible to the scan loop again.
3471
3476
  const nextAt = new Date(nowMs + OUTBOX_RETRY_DELAY_MS).toISOString();
3472
3477
  const withDelay = insertHeaderBeforeBody(raw, `X-Mailx-Retry-After: ${nextAt}`);
3473
- fs.writeFileSync(claimedPath, withDelay, "utf-8");
3478
+ try {
3479
+ fs.writeFileSync(claimedPath, withDelay, "utf-8");
3480
+ }
3481
+ catch (we) {
3482
+ console.error(` [outbox] FAIL writeBack ${claimedPath}: ${we?.message || we}`);
3483
+ }
3474
3484
  try {
3475
3485
  fs.renameSync(claimedPath, filePath);
3476
3486
  }
3477
- catch { /* file stays claimed; recovery sweeper will handle */ }
3487
+ catch (re) {
3488
+ // Loud — the file is now stuck in `.sending-` state
3489
+ // until the recovery sweeper's stale-claim timer
3490
+ // (5 min) reclaims it. User-visible as "stuck" in
3491
+ // the outbox view; cancelable via the new always-
3492
+ // allowed Cancel button.
3493
+ console.error(` [outbox] FAIL renameBack ${claimedPath} → ${filePath}: ${re?.message || re} — claim will sit until stale-recovery (5 min)`);
3494
+ }
3478
3495
  console.error(` [outbox] Send failed for ${file} (attempt ${attempt}, retry after ${nextAt}): ${e.message}`);
3479
3496
  }
3480
3497
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-imap",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",