From 9b15e086248a3a450272c867abe3fb691e762024 Mon Sep 17 00:00:00 2001 From: sususu Date: Wed, 5 Nov 2025 09:47:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AF=B7=E6=B1=82`/v1/messages/count=5F?= =?UTF-8?q?tokens`=20=E7=9A=84CanceledError=20=E4=B8=8D=E5=86=8D=E8=A2=AB?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E4=B8=BAERROR=20=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/routes/api.js | 12 ++++++++++++ src/services/claudeConsoleRelayService.js | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/routes/api.js b/src/routes/api.js index 898293bd..62729389 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -1085,6 +1085,18 @@ router.post('/v1/messages/count_tokens', authenticateApiKey, async (req, res) => return res.status(error.httpStatus).json(error.errorPayload) } + // 客户端断开连接不是错误,使用 INFO 级别 + if (error.message === 'Client disconnected') { + logger.info('🔌 Client disconnected during token count request') + if (!res.headersSent) { + return res.status(499).end() // 499 Client Closed Request + } + if (!res.destroyed && !res.finished) { + res.end() + } + return + } + logger.error('❌ Token count error:', error) if (!res.headersSent) { return res.status(500).json({ diff --git a/src/services/claudeConsoleRelayService.js b/src/services/claudeConsoleRelayService.js index 46c72996..58272cb5 100644 --- a/src/services/claudeConsoleRelayService.js +++ b/src/services/claudeConsoleRelayService.js @@ -317,7 +317,12 @@ class ClaudeConsoleRelayService { } } catch (error) { // 处理特定错误 - if (error.name === 'AbortError' || error.code === 'ECONNABORTED') { + if ( + error.name === 'AbortError' || + error.name === 'CanceledError' || + error.code === 'ECONNABORTED' || + error.code === 'ERR_CANCELED' + ) { logger.info('Request aborted due to client disconnect') throw new Error('Client disconnected') }