如何解决如何从控制器中的循环返回错误?
我显示了sql结构,我要插入的数据和代码。然后我暴露出问题所在。
这是一个简单的电子商务项目。问题与订单创建(POST)
有关sql结构:
数据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 举报,一经查实,本站将立刻删除。