立即修复您的 Express 错误处理
Express 可能是 Node.js 世界中最具影响力的软件包之一。它为我们提供了极其易于使用的 REST API 构建接口。它如此受欢迎,以至于任何可以放入中间件的东西,可能都已经有一个为 Express 而生的了。比如 pino、jwt、validator、fileupload、basic-auth、http-proxy 等等。难怪人们喜欢使用它。
承诺、异步、等待
Promises 现在是异步操作的标准,特别是因为我们还获得了异步函数和 await 关键字,这完全消除了对回调的需要,从而避免了所谓的回调地狱。
现在你会认为世界上最受欢迎的软件包之一应该可以与它们兼容,对吗?其实并非如此。
Express 最初开发时,Promise 还未真正成为标准,所以大家都在使用回调。虽然 JS 世界已经发展,但仍然有很多基于回调的 API,尤其是在 Node 本身中,例如fs模块。幸运的是,它有一个版本也支持 Promise API,或者我们可以使用一个名为promisify的工具。
快递有点糟糕
Express 的开发并不活跃,这可以理解——说到底,它的设计初衷就是要保持开放和极简主义。既然已经很棒了,何必费心去改变呢?
只不过 Express 的第 5 版实际上已经“开发”中了。这个版本已经持续了7 年多了——2014 年发布了 5.0.0-alpha1,它确实改进了一些地方,包括这个主要问题——Promises的错误处理。
是的,如果您阅读错误处理的文档,您就会了解到承诺的错误处理不是由 Express 完成的 - 除非您正在运行 Express 5,否则您必须自己完成。
那么,当你忽略文档时会发生什么?你会遇到 Node.js 中最严重的异常——未处理的 Promise 拒绝,如果你使用的是较新的 Node.js,默认情况下会导致进程崩溃。你的 Express 错误处理程序肯定不会被调用,甚至响应也不会发送到客户端,所以你甚至不会看到 500 内部服务器错误。只是超时而已。
如何不处理异步错误的示例:
const express = require("express");
const app = express();
app.get("/boom", (req, res) => {
throw "This will be handled";
});
app.get("/boomasync", async (req, res) => {
throw "This will not be handled";
});
app.use((err, req, res, next) => {
if (res.headersSent) {
return next(err);
}
console.error(err);
res.status(500).send("Oh no!");
});
app.listen(3000, () => console.log("Listening on 3000!"));
有趣的是,很长一段时间以来,我相信 Node.js 14 仍然是这样,未处理的 Promise 拒绝只会在控制台中生成丑陋的日志。这个默认设置很长时间没有改变,因为人们担心它不太方便用户使用。我鼓励你查看PR并发表相关帖子。
一个极其邪恶的想法😈
使固定
有很多方法可以解决这个问题。你可以直接.catch
在每个处理程序后面加上。你可以使用 Express 5(alpha 版本)。你可以使用自定义路由器或中间件来处理这个问题。你可以使用一些神奇的修补包,比如express-async-errors。你也可以不使用 Express。
所有这些都有一些权衡,但我很乐意在现有代码库中修补 Express 的内部机制。对于新项目,我宁愿使用比 Express 更好的工具。
TypeScript
我对 Express 的另一个问题是它的 TypeScript 支持。它的定义假设 Request 对象始终相同,但实际情况完全不同。添加新字段req
是依赖注入的常用方法。看一下pino 如何与 Express 集成。它添加了一个req.log
可以在处理程序中使用的对象。然而,由于定义是常量,当你尝试使用它时,TypeScript 会对你的代码发出警告。
当然,您可以始终自己声明类型,也可以使用模块扩充,但这不是 da wae。
最后的话
Express 有很多替代方案——Koa、Hapi、Fastify、Hono、Nest.js 只是其中的几个例子。我个人比较喜欢 Koa。从表面上看,它与 Express 非常相似,只是做了一些细微的修改,但生态系统规模要小得多。绝对值得一试。
我发现很多高级开发人员都不知道这个问题,所以一定要问问你的同事,这可能是一个有趣的面试问题。我甚至觉得这么晚才发帖有点蠢。
编码愉快!
鏂囩珷鏉ユ簮锛�https://dev.to/pr0gramista/fix-your-express-error-handling-now-4h2l