diff --git a/src/api/routes/deliveryParse.js b/src/api/routes/deliveryParse.js index 1ca9d4d..080aee6 100644 --- a/src/api/routes/deliveryParse.js +++ b/src/api/routes/deliveryParse.js @@ -31,7 +31,7 @@ function isPdfUpload(file) { // ─── SSE helpers ──────────────────────────────────────────────────────────────── function sseWrite(res, event, data) { - if (res.writableEnded) return; + if (res.writableEnded || res.destroyed) return; res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`); } @@ -276,8 +276,21 @@ async function parseDocumentManifest({ req, res, pages, sourceLabel }) { }), }); + const onDisconnect = () => { + if (!res.writableEnded) { + orbiter.abort(); + } + }; + req.on('close', onDisconnect); + res.on('close', onDisconnect); + // ── Process all pages in one batch ─────────────────────────────── try { + if (res.destroyed || req.destroyed) { + orbiter.abort(); + return; + } + const pageContent = pages .map((p, idx) => `--- Page ${idx + 1} of ${pages.length} ---\n${p}`) .join('\n\n'); @@ -301,9 +314,16 @@ ${pageContent}`; currentPage = 1; await orbiter.run({ prompt, model, tools: [outputManifestTool] }); } catch (err) { - if (!res.writableEnded) { + if (!res.writableEnded && !res.destroyed) { sseWrite(res, 'error', { message: 'LLM processing failed: ' + err.message }); } + } finally { + req.off('close', onDisconnect); + res.off('close', onDisconnect); + } + + if (res.writableEnded || res.destroyed) { + return; } // ── Final result ─────────────────────────────────────────────────