From 39a72e3e7274228accf1dcb8b79c3cb30307b592 Mon Sep 17 00:00:00 2001 From: shaw Date: Wed, 20 Aug 2025 23:50:42 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DJSON=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E5=AF=BC=E8=87=B4=E7=9A=84"Unexpected=20end?= =?UTF-8?q?=20of=20JSON=20input"=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除express.json()的verify函数中危险的buffer修改逻辑 - 该逻辑直接修改body-parser正在处理的原始buffer,导致数据损坏 - 改进JSON解析错误中间件,支持更多错误模式识别 - 将内部500错误改为用户友好的400错误响应 - 修复了Claude CLI客户端连接时的JSON解析问题 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/app.js | 44 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/src/app.js b/src/app.js index 1a6a7d56..9fca57eb 100644 --- a/src/app.js +++ b/src/app.js @@ -141,55 +141,33 @@ class Application { if (buf && buf.length && !buf.toString(encoding || 'utf8').trim()) { throw new Error('Invalid JSON: empty body') } - - // Unicode 字符清理 - 清理无效的 UTF-16 代理对 - if (buf && buf.length) { - try { - const str = buf.toString(encoding || 'utf8') - // 移除无效的 UTF-16 代理对字符 - const cleanedStr = str.replace( - /[\uDC00-\uDFFF](?![\uD800-\uDBFF])|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/g, - '\uFFFD' - ) - - // 如果字符串被清理过,重新写入buffer - if (cleanedStr !== str) { - logger.warn('🧹 Cleaned invalid Unicode characters from request body') - const cleanedBuf = Buffer.from(cleanedStr, encoding || 'utf8') - // 将清理后的内容复制回原buffer - cleanedBuf.copy(buf, 0) - // 调整buffer长度 - buf._charsWritten = cleanedBuf.length - } - } catch (error) { - logger.warn( - '⚠️ Unicode cleaning failed, proceeding with original buffer:', - error.message - ) - } - } + // 注意:不在这里修改buffer,避免导致JSON解析错误 } }) ) this.app.use(express.urlencoded({ extended: true, limit: '10mb' })) - // 🧹 Unicode 错误处理中间件 + // 🧹 JSON 解析错误处理中间件 this.app.use((err, req, res, next) => { if (err instanceof SyntaxError && err.status === 400 && 'body' in err) { - // 检查是否是Unicode相关的JSON解析错误 + // JSON 解析错误统一处理 + logger.warn('🚨 JSON parsing error detected:', err.message) + + // 检查是否是常见的JSON解析错误 if ( + err.message.includes('Unexpected end of JSON input') || + err.message.includes('Unexpected token') || + err.message.includes('Expected property name') || + err.message.includes('in JSON at position') || err.message.includes('surrogate') || err.message.includes('UTF-16') || err.message.includes('invalid character') ) { - logger.warn('🧹 Detected Unicode JSON parsing error, attempting recovery:', err.message) - return res.status(400).json({ type: 'error', error: { type: 'invalid_request_error', - message: - 'The request body contains invalid Unicode characters. Please ensure your text uses valid UTF-8 encoding and does not contain malformed surrogate pairs.' + message: 'Invalid JSON format in request body. Please ensure the request contains valid JSON data.' } }) }