fix: 修复JSON解析错误导致的"Unexpected end of JSON input"问题

- 移除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 <noreply@anthropic.com>
This commit is contained in:
shaw
2025-08-20 23:50:42 +08:00
parent cb29b3f7e4
commit 39a72e3e72

View File

@@ -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.'
}
})
}