微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从控制器中的循环返回错误?

如何解决如何从控制器中的循环返回错误?

显示sql结构,我要插入的数据和代码。然后我暴露出问题所在。

这是一个简单的电子商务项目。问题与订单创建(POST)

有关

sql结构:

enter image description here

数据JSON格式:

{
    "user": {
        "email": "test@test.com","role": "administrator","userId": 63
    },"items": [
        {
            "added": 2,"id": 6,"name": "Le Classique","price": 5
        },{
            "added": 5,"id": 2,"price": 5
        }
    ]
}

NodeJS控制器功能

exports.create = async (req,res,next) => {
   const formData = req.body

   const newOrder = {
      user_id: formData.user.userId,date: new Date()
   }

   const newOrderItems = formData.items

   try {
     await db.query(
       "INSERT INTO orders SET ?",newOrder,(err,results) => {
         if (err) {
             res.status(500).send("Erreur d'écriture des données")
         } else {
             newOrder.id = results.insertId

             for (let i = 0; i < newOrderItems.length; i++) {

               let orderItems = {
                 orders_id: newOrder.id,items_id: newOrderItems[i].id,quantity: newOrderItems[i].added
               }

               db.query(
                 "INSERT INTO order_items SET ?",orderItems,results) => {
                   if (err) {
                     // throw an error? and cancel everything?
                   }
                 }
              )
             }

             res.status(201).send({
               order: newOrder
             })

         }
     })

   } catch (err) {
       return next(err)
   }
 }

我的代码正在运行,但是当我尝试输入错误的商品ID时我遇到了错误问题。例如,第一项作为ID 6,但数据库中没有具有该ID的项。因此,他从循环中跳过了该项目(可能有一个我们没有看到的sql错误),并继续了另一个循环(并向成功注册了下一个)。

如果我放throw new Error("This is the error text")服务器崩溃

每个循环之后,它发送201状态。但是我想在这种情况下返回错误并取消订单。你觉得有可能吗?

谢谢


编辑评论: (结果console.log)

Query {
  _events: [Object: null prototype] {},_eventsCount: 0,_maxListeners: undefined,_callback: undefined,_callSite: Error
      at Pool.query (/home/jer/projets/coco/coco/backend/node_modules/MysqL/lib/Pool.js:199:23)
      at exports.create (/home/jer/projets/coco/coco/backend/controllers/Orders.controller.js:89:32)
      at Layer.handle [as handle_request] (/home/jer/projets/coco/coco/backend/node_modules/express/lib/router/layer.js:95:5)
      at next (/home/jer/projets/coco/coco/backend/node_modules/express/lib/router/route.js:137:13)
      at module.exports (/home/jer/projets/coco/coco/backend/middlewares/Auth.middleware.js:17:13)
      at Layer.handle [as handle_request] (/home/jer/projets/coco/coco/backend/node_modules/express/lib/router/layer.js:95:5)
      at next (/home/jer/projets/coco/coco/backend/node_modules/express/lib/router/route.js:137:13)
      at Route.dispatch (/home/jer/projets/coco/coco/backend/node_modules/express/lib/router/route.js:112:3)
      at Layer.handle [as handle_request] (/home/jer/projets/coco/coco/backend/node_modules/express/lib/router/layer.js:95:5)
      at /home/jer/projets/coco/coco/backend/node_modules/express/lib/router/index.js:281:22,_ended: false,_timeout: undefined,_timer: Timer { _object: [Circular],_timeout: null },sql: 'INSERT INTO orders SET ?',values: { user_id: 63,date: 2020-09-04T15:01:16.405Z },typeCast: true,nestTables: false,_resultSet: null,_results: [],_fields: [],_index: 0,_loadError: null,[Symbol(kCapture)]: false
}

解决方法

您可以添加临时数组,以在添加项目时维护来自SQL的错误,并且在循环之后,可以检查用于发送响应的数组的长度。由于您使用的是回调,因此我们必须维护一个单独的计数器来检查是否所有请求都返回了

在示例代码下方。

    exports.create = async (req,res,next) => {
const formData = req.body

const newOrder = {
    user_id: formData.user.userId,date: new Date()
}

const newOrderItems = formData.items

try {
    await db.query(
        "INSERT INTO orders SET ?",newOrder,(err,results) => {
            if (err) {
                return res.status(500).send("Erreur d'écriture des données")
            }
            newOrder.id = results.insertId
            const errData = [];
            let queryCounter = 0;
            for (let i = 0; i < newOrderItems.length; i++) {

                let orderItems = {
                    orders_id: newOrder.id,items_id: newOrderItems[i].id,quantity: newOrderItems[i].added
                }

                db.query(
                    "INSERT INTO order_items SET ?",orderItems,results) => {
                        // keeping track of records tried
                        queryCounter++;
                        if (err) {
                            errData.push(err);
                        }

                        // check if all callback came back
                        if (queryCounter === newOrderItems.length) {
                            if (errData.length) {
                                return res.status(500).send({
                                    message: 'Failed to insert items',errors: errItems
                                });
                            }

                            return res.status(201).send({
                                order: newOrder
                            });
                        }

                    }
                )
            }
        })

} catch (err) {
    return next(err)
}

}

建议:转向承诺而不是使用回调,它们会给出类似这样的棘手情况。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?