Mongoose+Express中Async-Await错误处理及EJS渲染最佳实践
Mongoose + Express + EJS 渲染数据页面的最佳实践
你的困惑点很典型——既要用现代的Async/Await语法,又不能忽略错误处理。直接给出最优解:给Async/Await搭配Try/Catch做错误捕获,兼顾语法简洁性和错误处理能力,这也是当前Node.js生态的推荐实践。
一、改进方法1:给Async/Await添加错误处理
方法1的问题不是用了Async/Await,而是没有捕获await可能抛出的异常。Mongoose的查询方法在失败时会抛出错误,我们只需要用try/catch包裹异步操作,就能像回调模式一样处理错误:
app .route("/") .get(async (req, res) => { try { const items = await imgModel.find({}); res.render("home", { items }); } catch (err) { // 处理数据库查询错误,可根据需求返回错误页面或提示 console.error("数据库查询失败:", err); res.status(500).render("error", { message: "加载数据失败,请稍后重试" }); } }) .post((req, res) => { res.render("home"); });
二、为什么不推荐方法2的回调模式
回调模式虽然能处理错误,但存在明显缺陷:
- 多层异步操作会陷入回调地狱,代码可读性和维护性急剧下降;
- 错误处理逻辑分散在每个回调里,难以统一管理;
- Async/Await是ES2017引入的标准语法,已经成为Node.js异步编程的主流,社区生态更倾向于这种写法。
三、进阶优化:全局错误处理中间件
如果你的项目有很多异步路由,每个都写try/catch会重复代码。可以用Express的全局错误处理中间件来统一捕获Async/Await抛出的错误:
- 定义全局错误处理中间件:
app.use((err, req, res, next) => { console.error("服务器错误:", err); // 统一返回500错误页面,也可根据错误类型定制响应 res.status(500).render("error", { message: "服务器内部错误" }); });
- 修改异步路由,将错误传递给全局中间件:
app .route("/") .get(async (req, res, next) => { try { const items = await imgModel.find({}); res.render("home", { items }); } catch (err) { next(err); } }) .post((req, res) => { res.render("home"); });
还可以封装一个异步路由包装函数,自动捕获错误并传递给next,进一步简化代码:
const asyncHandler = (fn) => (req, res, next) => { Promise.resolve(fn(req, res, next)).catch(next); }; // 使用包装函数简化路由写法 app .route("/") .get(asyncHandler(async (req, res) => { const items = await imgModel.find({}); res.render("home", { items }); })) .post((req, res) => { res.render("home"); });
这样既保留了Async/Await的简洁性,又实现了统一的错误处理,是目前最推荐的实践方案。
内容的提问来源于stack exchange,提问作者Shawemra_Lvr
相关产品推荐
相关产品推荐

