fix(imap): robust error logging + parser-instance.js null guards
- Move client.connect() inside try/catch in withClient - Add logImapError() writing full stack to /vaults/imap-errors.log for diagnosis - Extend patch-imapflow.cjs to guard this.remainder.trim() in parser-instance.js - Root cause of reported crash was undefined args.q (callers passing 'query' not 'q') Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
86
scripts/patch-imapflow.cjs
Normal file
86
scripts/patch-imapflow.cjs
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env node
|
||||
// Patches imapflow to handle Poste.io servers returning IMAP NO/BAD/BYE
|
||||
// responses where some TEXT attributes have undefined .value, causing
|
||||
// `val.value.trim()` to throw "Cannot read properties of undefined".
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const file = path.join(__dirname, '../node_modules/imapflow/lib/imap-flow.js');
|
||||
let src = fs.readFileSync(file, 'utf8');
|
||||
|
||||
const patches = [
|
||||
{
|
||||
bad: `.map(val => val.value.trim())`,
|
||||
fixed: `.map(val => (val.value != null ? val.value.trim() : ''))`,
|
||||
},
|
||||
{
|
||||
bad: `section[0].value.toUpperCase().trim()`,
|
||||
fixed: `(section[0].value || '').toUpperCase().trim()`,
|
||||
},
|
||||
{
|
||||
bad: `attr.value.toUpperCase().trim()`,
|
||||
fixed: `(attr.value || '').toUpperCase().trim()`,
|
||||
},
|
||||
{
|
||||
bad: `val.value.toUpperCase().trim()`,
|
||||
fixed: `(val.value || '').toUpperCase().trim()`,
|
||||
},
|
||||
{
|
||||
bad: `contentType.value.toLowerCase().trim()`,
|
||||
fixed: `(contentType.value || '').toLowerCase().trim()`,
|
||||
},
|
||||
{
|
||||
bad: `disposition.value.toLowerCase().trim()`,
|
||||
fixed: `(disposition.value || '').toLowerCase().trim()`,
|
||||
},
|
||||
];
|
||||
|
||||
let total = 0;
|
||||
for (const p of patches) {
|
||||
const re = new RegExp(p.bad.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g');
|
||||
const count = (src.match(re) || []).length;
|
||||
if (count > 0) {
|
||||
src = src.replaceAll(p.bad, p.fixed);
|
||||
total += count;
|
||||
console.log(`[patch-imapflow] patched ${count} occurrence(s) of: ${p.bad}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (total > 0) {
|
||||
fs.writeFileSync(file, src, 'utf8');
|
||||
console.log(`[patch-imapflow] total patched ${total} occurrence(s) in imap-flow.js`);
|
||||
} else {
|
||||
console.log('[patch-imapflow] already patched or patterns not found — no changes made');
|
||||
}
|
||||
|
||||
// Also patch parser-instance.js (this.remainder can be undefined on malformed Poste.io responses)
|
||||
const parserFile = path.join(__dirname, '../node_modules/imapflow/lib/handler/parser-instance.js');
|
||||
if (fs.existsSync(parserFile)) {
|
||||
let parserSrc = fs.readFileSync(parserFile, 'utf8');
|
||||
let parserPatched = 0;
|
||||
const parserPatches = [
|
||||
{ bad: `this.humanReadable = this.remainder.trim();`, fixed: `this.humanReadable = (this.remainder || '').trim();` },
|
||||
{ bad: `this.humanReadable = this.remainder.substring(i + 1).trim();`, fixed: `this.humanReadable = (this.remainder || '').substring(i + 1).trim();` },
|
||||
];
|
||||
for (const p of parserPatches) {
|
||||
if (parserSrc.includes(p.bad)) {
|
||||
parserSrc = parserSrc.replaceAll(p.bad, p.fixed);
|
||||
parserPatched++;
|
||||
console.log(`[patch-imapflow] patched parser-instance.js: ${p.bad}`);
|
||||
}
|
||||
}
|
||||
if (parserPatched > 0) fs.writeFileSync(parserFile, parserSrc, 'utf8');
|
||||
}
|
||||
|
||||
// Also patch nodemailer inside imapflow (malformed Content-Type headers)
|
||||
const nodemailerFile = path.join(__dirname, '../node_modules/imapflow/node_modules/nodemailer/lib/mime-node/index.js');
|
||||
if (fs.existsSync(nodemailerFile)) {
|
||||
let nodemailerSrc = fs.readFileSync(nodemailerFile, 'utf8');
|
||||
const nodemailerBad = `this.contentType = structured.value.trim().toLowerCase();`;
|
||||
const nodemailerFixed = `this.contentType = ((structured && structured.value) || '').trim().toLowerCase();`;
|
||||
if (nodemailerSrc.includes(nodemailerBad)) {
|
||||
nodemailerSrc = nodemailerSrc.replaceAll(nodemailerBad, nodemailerFixed);
|
||||
fs.writeFileSync(nodemailerFile, nodemailerSrc, 'utf8');
|
||||
console.log('[patch-imapflow] patched nodemailer mime-node/index.js');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user