专栏首页Fundebug如何处理Express异常?

如何处理Express异常?

译者按:根据墨菲定律:“有可能出错的事情,就会出错”。那么,既然代码必然会出错,我们就应该处理好异常。

本文采用意译,版权归原作者所有

处理异常是编程非常重要的一点。我们的程序依赖于第三方服务、数据库以及我们的用户,一切都不可预料。数据库可能会宕机,第三方服务可能会崩溃,用户可能会使用错误的参数调用我们的接口。

为了处理各种复杂的情况,我们必须处理好代码异常,下面是代码示例:

app.get("/users/:id", (req, res) => {
    const userId = req.params.id;
    if (!userId) {
        return res.sendStatus(400).json({
            error: "Missing id"
        });
    }

    Users.get(userId, (err, user) => {
        if (err) {
            return res.sendStatus(500).json(err);
        }

        res.send(users);
    });
});

代码中处理了异常,但是存在问题:

  • 在多处代码处理异常
  • 没有使用 Express 的异常处理模块来统一处理异常

接下来,我们来一步步优化代码异常处理。

Express 异常处理中间件

所有 Express 的路由处理函数都有第三个参数next,它可以用来调用下一个中间件,也可以将错误传递给错误处理中间件:

app.get("/users/:id", (req, res, next) => {
    const userId = req.params.id;
    if (!userId) {
        const error = new Error("missing id");
        error.httpStatusCode = 400;
        return next(error);
    }

    Users.get(userId, (err, user) => {
        if (err) {
            err.httpStatusCode = 500;
            return next(err);
        }

        res.send(users);
    });
});

使用next(err),Express 就知道出错了,并把这个错误传递给错误处理模块。为了处理这些错误,需要添加一个中间件,它有 4 个参数:

app.use((err, req, res, next) => {
    // log the error...
    res.sendStatus(err.httpStatusCode).json(err);
});

这样,我们就可以使用中间件统一处理错误了。但是,现在的代码有些重复:创建错误,指定 HTTP 状态码,使用 next(err)…

Fundebug是全栈 JavaScript 错误监控平台,支持各种前端和后端框架,可以帮助您第一时间发现 BUG!

boom

boom是一个兼容 HTTP 的错误对象,他提供了一些标准的 HTTP 错误,比如 400(参数错误)等。

const boom = require("boom");
app.get("/users/:id", (req, res, next) => {
    const userId = req.params.id;
    if (!userId) {
        return next(boom.badRequest("missing id"));
    }

    Users.get(userId, (err, user) => {
        if (err) {
            return next(boom.badImplementation(err));
        }

        res.send(users);
    });
});

错误处理中间件需要稍作修改:

app.use((err, req, res, next) => {
    if (err.isServer) {
        // log the error...
        // probably you don't want to log unauthorized access
        // or do you?
    }
    return res.status(err.output.statusCode).json(err.output.payload);
});

Async/Await 错误处理

使用 Async/Await 之后,可以这样处理 Express 异常:

  • 将中间件使用 Promise 封装起来,使用 catch 统一处理异常
  • 在中间件中,直接抛出异常就可以了
const boom = require("boom");
// wrapper for our async route handlers
// probably you want to move it to a new file
const asyncMiddleware = fn => (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(err => {
        if (!err.isBoom) {
            return next(boom.badImplementation(err));
        }
        next(err);
    });
};
// the async route handler
app.get(
    "/users/:id",
    asyncMiddleware(async (req, res) => {
        const userId = req.params.id;
        if (!userId) {
            throw boom.badRequest("missing id");
        }

        const user = await Users.get(userId);
        res.json(user);
    })
);

参考

  • 验证 HTTP 请求参数可以使用joi模块
  • 打印日志可以使用winston或者pino模块

版权声明

转载时请注明作者 Fundebug以及本文地址: https://blog.fundebug.com/2017/12/06/handle-express-error/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JS的静态类型检测,有内味儿了

    我们知道 TypeScript 2.3 以后的版本支持使用--checkJs对.js文件进行类型检查和错误提示。 但是由于 JavaScript 是弱类型语言,...

    Daotin
  • 揭开微信小程序 Kbone 的神秘面纱

    微信小程序诞生至今,渗透到用户生活的方方面面,包括餐厅点餐,网上购物,乘车出行,挂号就医……

    binnie
  • 在 kbone 中实现小程序 svg 渲染

    2019 年底,微信小程序已经推出了近三个年头,我身边的前端开发者基本都做过至少一次小程序了。很多友商曾打算推动小程序进入 W3C 标准,而微信并不为所动,个人...

    binnie
  • 记一次移动光猫(GM219-S)安全测试

    顾翔老师开发的bugreport2script开源了,希望大家多提建议。文件在https://github.com/xianggu625/bug2testscr...

    小老鼠
  • Swagger-UI

    顾翔老师开发的bugreport2script开源了,希望大家多提建议。文件在https://github.com/xianggu625/bug2testscr...

    小老鼠
  • Vue + TypeScript 踩坑总结

    vue 和 TypeScript 结合的情况下,很多写法和我们平时的写法都不太一样,这里总结我项目开发过程中遇到的问题和问题的解决方案 有些问题可能还没解决,...

    xing.org1^
  • vue中eventBus的使用

    tianyawhl
  • 小程序同构方案 kbone 分析与适配

    在微信小程序的开发的过程中,我们会存在小程序和 H5 页面共存的场景,而让小程序原生和 web h5 独立开发,往往会遇到需要两套人力去维护。对开发者而言,加大...

    binnie
  • Kbone原理解析 & 小程序技术选型

    首先我们来看下普通Web端框架,以Vue框架为例,一份Vue模板对应一个组件,在代码构建阶段编译成调用Dom接口的JS函数,执行此JS函数就会创建出组件对应的D...

    binnie
  • 自动化测试selenium在小公司的成功实践

    顾翔老师开发的bugreport2script开源了,希望大家多提建议。文件在https://github.com/xianggu625/bug2testscr...

    小老鼠

扫码关注云+社区

领取腾讯云代金券