我运行一个 NodeJS 服务器,日志中有两种新的错误类型:
[2021-05-21T09:11:33.891Z] SyntaxError: Unexpected token h in JSON at position 0
at JSON.parse (<anonymous>)
at createStrictSyntaxError (~/server/node_modules/body-parser/lib/types/json.js:158:10)
at parse (~/server/node_modules/body-parser/lib/types/json.js:83:15)
at ~/server/node_modules/body-parser/lib/read.js:121:18
at invokeCallback (~/server/node_modules/raw-body/index.js:224:16)
at done (~/server/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (~/server/node_modules/raw-body/index.js:273:7)
at IncomingMessage.emit (events.js:323:22)
at IncomingMessage.EventEmitter.emit (domain.js:482:12)
at endReadableNT (_stream_readable.js:1204:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
堆栈跟踪仅显示 node_modules
路径,而不是在我的代码中出现此错误的位置。 stdout
日志也没有显示在那个时候可能导致此错误的原因。
处理 JSON 对象的服务器代码是:
// Use JSON parser (required to parse POST forms)
app.use((req, res, next) => {
bodyParser.json()(req, res, next);
});
app.use(bodyParser.urlencoded({extended: true}));
我在这个函数中添加了日志记录,以防将来我遇到同样的错误。
一般来说,我如何记录有关导致节点模块错误的请求的信息?
此错误源于用户,我无法复制它。发送JSON数据的客户端代码为:
// `id` indicates the ID of the video
var body = {
percent: percent,
videoId: id,
eventLabel: eventLabel
}
async function view() {
return await fetch("/viewership", {
method: "POST",
credentials: "include",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(body)
});
};
Chrome 调试器的网络选项卡显示此请求负载:
{percent: 0, videoId: ..., eventLabel: "play"}
答案 0 :(得分:1)
好吧,这就是我们所知道的。
IncomingMessage
(和传入的 http 请求)body-parser
模块JSON.parse()
显然应该是一个 JSON 正文代码是这样的:
if (strict) {
var first = firstchar(body)
if (first !== '{' && first !== '[') {
debug('strict violation')
throw createStrictSyntaxError(body, first)
}
}
因此,它显然未能在 JSON 上找到前导 {
或 [
,而是找到了 h
。
我们可以从该信息推断传入的 http 请求(可能是 POST)应该具有 JSON 正文,但数据不是合法的 JSON。
您调试的第一点是准确查看请求中的 JSON 正文数据。如果此请求来自浏览器,您可以查看调试器的 Chrome 网络选项卡,查看浏览器向您的服务器发送的确切内容。
因此,这很可能是客户端引起的错误。当数据不是 JSON 时,内容类型被错误地设置为 JSON,或者客户端应该发送 JSON,但没有发送正确的 JSON。
如果您能向我们展示用于此的客户端代码,我们或许能够发现该代码中的错误。
<块引用>您是否知道一种记录任何引发错误的请求的方法,例如对于未来与 JSON 无关的其他不良请求?
当正文解析器得到错误的 JSON 时,它会调用带有异常的 Express 错误处理程序。如果您转到此 Express doc page 上的“写入错误处理程序”,它将向您展示如何捕获这些错误并通过返回客户端的一些错误页面和尽可能多的日志记录来处理它们。