[英]Knexjs and es6 Try/Catch causing an Unhandled Promise Rejection Warning?
I've been working on a new application that uses PostgreSQL and Knexjs as a query builder, but have been running into an issue I'm not sure how to handle. 我一直在研究使用PostgreSQL和Knexjs作为查询生成器的新应用程序,但是遇到了一个我不确定如何处理的问题。
I have a route handler that looks like so: 我有一个路由处理程序,看起来像这样:
export const getSingleUser = async(req, res) => {
let respObj = {
status: 'fail',
message: 'User does not exist'
};
try {
const user = await knex('users').where('id', req.params.id).first();
if (!user) {
res.send(respObj);
}
respObj = {
status: 'success',
data: user
};
res.send(respObj);
} catch(e) {
res.send(respObj);
}
};
It works great, until I throw a non-existent user ID into the mix. 效果很好,直到我将不存在的用户ID放入混合中为止。 I assumed the catch statement would handle the error if no user is found for the query, but that doesn't seem to work, it just spits out the respObj
in the try block. 我假设如果找不到该查询的用户,则catch语句将处理该错误,但这似乎不起作用,它只是在try块中吐出了respObj
。 So I added an if statement to check if the user object doesn't exist, and thats when I received the warning below: 因此,我添加了一条if语句来检查用户对象是否不存在,也就是在收到以下警告时:
(node:25711) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at validateHeader (_http_outgoing.js:503:11)
at ServerResponse.setHeader (_http_outgoing.js:510:3)
at ServerResponse.header (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/node_modules/express/lib/response.js:767:10)
at ServerResponse.send (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/node_modules/express/lib/response.js:170:12)
at ServerResponse.json (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/node_modules/express/lib/response.js:267:15)
at ServerResponse.send (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/node_modules/express/lib/response.js:158:21)
at _callee3$ (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/src/controllers/userController.js:45:7)
at tryCatch (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/node_modules/regenerator-runtime/runtime.js:65:40)
at Generator.invoke [as _invoke] (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/node_modules/regenerator-runtime/runtime.js:303:22)
at Generator.prototype.(anonymous function) [as next] (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/node_modules/regenerator-runtime/runtime.js:117:21)
at step (/Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/src/controllers/userController.js:14:191)
at /Users/munsterberg/Sites/fullstack_workspace/esports-manager/services/project/src/controllers/userController.js:14:361
at <anonymous>
(node:25711) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:25711) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Can anyone provide more info on why this is happening, and whats the fix? 谁能提供更多有关为何发生这种情况的信息,以及解决方法是什么?
Work around 解决
A response is sent twice in the try
block if the user does not exist. 如果用户不存在,则在try
块中发送两次响应。 Presumably this indirectly accounts for the error raised: 大概这间接地解决了引发的错误:
"Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client". “错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后,无法设置标头”。
Redirecting the "user does not exist" case to the catch block, by throwing an error, could be a work around to avoid the issue in the first place. 通过抛出一个错误,将“用户不存在”的情况重定向到catch块,可能是一种变通方法,首先可以避免该问题。 A cut-down example: 简化示例:
export const getSingleUser = async(req, res) => {
try {
const user = await knex('users').where('id', req.params.id).first();
if (!user) {
throw new Error(" user does not exist");
}
res.send( {
status: 'success',
data: user
});
} catch(e) {
// console.log(e); // debug if needed
res.send( {
status: 'fail',
message: 'User does not exist'
});
}
};
No reason for why the try/catch
block generates an uncaught promise rejection error stands out to me. 在我看来, try/catch
块为什么会产生未捕获的诺言拒绝错误没有理由。 Perhaps res.send
has been coded to do something unusual in case of errors, say by raising a rejected promise asynchronously, but unfortunately that is only conjecture on my part and the true reason may be something else entirely. 也许res.send
已被编码为在发生错误的情况下执行某些异常操作,例如通过异步提出被拒绝的承诺,但不幸的是,这只是我的推测,真正的原因可能完全是其他原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.