node.js - 如何使用NodeJS/Express处理和返回API中的错误

标签 node.js api express error-handling

我使用带有快速框架的NodeJS和mongodb创建一个API,以存储我的数据。

我有一个注册功能,可以完成3个主要任务。

  • 创建新的。
  • 创建一个 token 并将其与用户关联。
  • 发送电子邮件。

    module.exports.register = function(req,res){
    var input = req.body;
    var token = uuid.v4();
    
    
    // Create a new user
    var user = new User ({
    
        username: input.username,
        email: input.email,
        password: input.password,
        active: false
    
    });
    
    user.save(function(err) {
    
        if(err) return res.json({success: false, errors: 'Failed To Create User'});
    
    });
    
    
    // Create a new Token
    var newToken = createToken('new', null, user._id);
    
    
    // Assign New Token To New User
    if(newToken) {
    
    
        user.tokens.push(newToken._id);
    
    
        user.save(function(err) {
    
            if(err) return res.json({success: false, errors: 'Failed To Save User Token'});
    
        });
    
    }
    
    
    // Send Email To User
    var mailData = {
    
        from: 'deleted@hotmail.com',
        to: input.email,
        subject: 'Activate Your Account',
        text: 'http://localhost:8080/api/auth/activate/' + token
    
    }
    
    mail.messages().send(mailData, function(err, body) {
    
        if(err) return res.json({ success: false, errors: 'Failed To Send Email' });
    
    });
    
    
    return res.json({ 
        success: true, 
        status: 'Successfully Registered User, Check Email To Activate' 
    });
    


  • 现在,即使在创建用户或 token 或发送电子邮件时出错。它总是会返回它已成功注册用户的信息。我怎样才能更好地进行重组/处理?

    我还有一个问题,如果电子邮件无法发送用户并且 token 已经创建,我该如何解决此问题?我会创建重新发送激活功能吗?

    最佳答案

    您应该删除最终的return语句(从代码末尾开始),如果没有错误,请在每个回调函数内的正确位置返回。

    如果您在函数主体中发送响应,则回调将永远不会有运行的机会。因此,您必须嵌套回调,并且仅在满足以下条件时才调用res.send

  • 由于错误或
  • 而提前返回
  • ,如果一切都完成了。

  • 例如
    // Create a new user
    var user = new User ({
        username: input.username,
        email: input.email,
        password: input.password,
        active: false
    });
    
    user.save(function(err) {
        if(err) return res.json({success: false, errors: 'Failed To Create User'});
    
        // Create a new Token
        var newToken = createToken('new', null, user._id);
        // Assign New Token To New User
        if(newToken) {
            user.tokens.push(newToken._id);
            user.save(function(err) {
                if(err) return res.json({success: false, errors: 'Failed To Save User Token'});
    
                // Send Email To User
                var mailData = {
                    from: 'deleted@hotmail.com',
                    to: input.email,
                    subject: 'Activate Your Account',
                    text: 'http://localhost:8080/api/auth/activate/' + token
                }
    
                mail.messages().send(mailData, function(err, body) {
                    if(err) return res.json({ success: false, errors: 'Failed To Send Email' });
    
                    return res.json({
                        success: true,
                        status: 'Successfully Registered User, Check Email To Activate'
                    });
                });
            });
        }
    });
    

    异步替代品

    不幸的是,有了node.js,您应该习惯并了解回调。即使您大部分时间最终还是使用其他东西。代码的结构方式更加简洁合理,但在node.js中不起作用,因为您必须等待回调完成才能从函数返回。

    但是,回调是默认的,但是是处理异步逻辑的最差的机制之一。如果您想以不同的方式构造代码,则有很多选择。这里只是几个:
  • 使用promise而不是回调。

  • 在您的情况下,您的数据库库( Mongoose 或sequelize?)应该内置一些东西,使您可以像这样编写代码:
    user.save()
      .then(function () {
          // step 1
      })
      .then(funciton () {
          // step 2
      })
      .done()
    

    这种编程风格非常值得学习,它将使您的代码比回调更易读。 callbacks vs promises
  • 使用Koa代替express。

  • Koa,是同一个人编写的下一代 express 。它使用生成器而不是回调,这意味着您可以编写如下所示的代码:
    // this is just an example
    var result = user.save();
    if (result.error) return res.send({success : false, ...});
    
    user.token = getNewToken();
    user.update();
    if (result.error) return res.send({success : false, ...});    
    
    return res.send({success : true, message : "Good news, no errors"});
    

    生成器/(aka异步函数)是Javascript前进的方向,但是有一个学习曲线可以开始使用。在幕后,发生了一些非常复杂的事情,使异步代码看起来完全像同步代码一样。基本上,这些函数知道如何暂停执行,直到再次需要它们为止。

    从回调开始

    就像我说的,回调并不是那么好。但是,您应该习惯使用它们。它们是node.js的基本构建块,需要一段时间才能适应更好的替代方案。习惯他们也很重要,因为否则您将不明白为什么其他选择更好。

    祝你好运,注意循环内的回调:)

    关于node.js - 如何使用NodeJS/Express处理和返回API中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35100468/

    相关文章:

    node.js - Synology SSL 和 nodejs

    javascript - 如何在express js中检查每个请求是否有cookie

    javascript - 如何从 API 中的链接获取数据?

    javascript - 具有 JSON 和二进制数据传递功能的 Express Body Parser

    javascript - 如何渲染jade模板并使用jquery在div中调用它?

    node.js - 是否可以在 express + node js 中进行重定向?

    node.js - Google存储桶是公共(public)的,但仍然无法访问文件

    node.js - 在 mongodb-native NodeJS 中为集群使用单个连接池与为每个子进程使用多个连接池

    http - 将接口(interface)写入 Web 服务 API

    Django REST Framework 和 Vue.js 在发布时抛出 IntegrityError