From f1457b02caaf8f71042fd1fdc70fef460528e096 Mon Sep 17 00:00:00 2001 From: mstfyldz Date: Wed, 12 Aug 2026 13:02:40 +0300 Subject: [PATCH] fix(chat): allow AI to finish and save responses even if client disconnects --- src/controllers/chat.controller.ts | 48 +++++++++++++++++++----------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/src/controllers/chat.controller.ts b/src/controllers/chat.controller.ts index e720eff..aa3dd48 100644 --- a/src/controllers/chat.controller.ts +++ b/src/controllers/chat.controller.ts @@ -41,9 +41,15 @@ function startSse(res: Response) { } function sseWrite(res: Response, payload: Record) { - res.write(`data: ${JSON.stringify(payload)}\n\n`); - if (typeof (res as any).flush === 'function') { - (res as any).flush(); + if (res.destroyed || res.writableEnded) return; + try { + res.write(`data: ${JSON.stringify(payload)}\n\n`); + if (typeof (res as any).flush === 'function') { + (res as any).flush(); + } + } catch (err) { + // Client disconnect olduysa yazma hatasını yoksay, arka planda AI'ın + // yanıt üretmeyi bitirip veritabanına kaydetmesine izin ver. } } @@ -198,15 +204,19 @@ export const chatMessage = async (req: AuthenticatedRequest, res: Response) => { } } - sseWrite(res, { done: true, newTitle, messageId: aiMessage?.id || null }); - res.end(); + if (!res.destroyed && !res.writableEnded) { + sseWrite(res, { done: true, newTitle, messageId: aiMessage?.id || null }); + res.end(); + } } catch (error: any) { console.error('Chat Error:', error); - if (!res.headersSent) { - res.status(500).json({ error: error.message || 'Internal Server Error' }); - } else { - sseWrite(res, { error: error.message || 'Internal Server Error' }); - res.end(); + if (!res.destroyed && !res.writableEnded) { + if (!res.headersSent) { + res.status(500).json({ error: error.message || 'Internal Server Error' }); + } else { + sseWrite(res, { error: error.message || 'Internal Server Error' }); + res.end(); + } } } }; @@ -281,15 +291,19 @@ export const sendThreadMessage = async (req: AuthenticatedRequest, res: Response } } - sseWrite(res, { done: true, newTitle, messageId: aiMessage?.id || null }); - res.end(); + if (!res.destroyed && !res.writableEnded) { + sseWrite(res, { done: true, newTitle, messageId: aiMessage?.id || null }); + res.end(); + } } catch (error: any) { console.error('Send Thread Message Error:', error); - if (!res.headersSent) { - res.status(500).json({ error: error.message || 'Internal Server Error' }); - } else { - sseWrite(res, { error: error.message || 'Internal Server Error' }); - res.end(); + if (!res.destroyed && !res.writableEnded) { + if (!res.headersSent) { + res.status(500).json({ error: error.message || 'Internal Server Error' }); + } else { + sseWrite(res, { error: error.message || 'Internal Server Error' }); + res.end(); + } } } };