有没有更好的方法来处理快递中的错误?
Posted
技术标签:
【中文标题】有没有更好的方法来处理快递中的错误?【英文标题】:Is there a better way to handle errors in express? 【发布时间】:2021-04-06 14:43:16 【问题描述】:一段时间后,我正在快速构建一个 API。这个应用程序可以帮助用户跟踪他们的吉他套路。以下是我的控制器中的 DELETE 函数示例以及可能引发的异常:
deleteOneRoutine = async (userId, routineId) =>
// If the given routineId is found in the DB
// AND the userId matches, delete it from DB
const selectedRoutine = await Routine.findOne(_id: routineId);
if (!selectedRoutine) return 400;
if (selectedRoutine.userId != userId) return 401;
const deleted = await selectedRoutine.remove();
if (!deleted) return 500;
return deleted;
这是接收这些错误代码的路由:
routineRouter.delete('/:routineId', async (req, res) =>
const userId = req.params.userId;
const routineId = req.params.routineId;
const deleted = await routineController.deleteOneRoutine(userId, routineId);
if (deleted === 400) res.status(400).send('Requested routine could not be found.')
else if (deleted === 401) res.status(401).send('Unauthorized user.')
else if (deleted === 500) res.status(500).send('Server error. Could not delete routine.')
else res.status(200).send(`Successfully deleted routine with ID $routineId`)
);
我想知道是否有更好的方法来处理这个问题,而不是手动从控制器传回错误代码。任何帮助将不胜感激!
【问题讨论】:
【参考方案1】:在 Express 中抛出错误并添加错误处理程序会更容易。
router.use((err, req, res, next) =>
res.status(500).send(err.message);
);
router.get('/path', async (req, res) =>
throw new Error('Can't delete!');
);
我认为错误中间件必须先出现,但我必须检查。
如果你需要特定的错误类型,你可以继承 Error;如果您希望能够传递代码,则可以在错误上添加一个属性(尽管我建议避免将路由逻辑(例如设置特定的 HTTP 代码)与业务逻辑(例如您的 deleteOneRoutine
函数)混合)
【讨论】:
【参考方案2】:我对返回值的当前类型不太满意——我认为返回一个带有错误属性中的错误或例程 ID 的对象会更有意义。但 IMO 更好的方法是传递 res
以便 deleteOneRoutine
可以自己完成。还要创建一个辅助函数来保持 DRY,并且不要忘记捕获异步函数抛出的可能异常:
deleteOneRoutine = async (userId, routineId, res) =>
const send = (code, message) => res.status(code).send(message);
const serverError = () => send(500, 'Server error. Could not delete routine.');
try
const selectedRoutine = await Routine.findOne(_id: routineId);
if (!selectedRoutine) return send(400, 'Requested routine could not be found.');
if (selectedRoutine.userId !== userId) return send(401, 'Unauthorized user.');
const deleted = await selectedRoutine.remove();
if (!deleted) return serverError();
send(200, `Successfully deleted routine with ID $deleted`);
catch(e)
serverError();
routineRouter.delete('/:routineId', (req, res) =>
const userId, routineId = req.params;
routineController.deleteOneRoutine(userId, routineId, res);
);
【讨论】:
不要敲你的代码,但我认为让deleteOneRoutine
“意识到”它的“网络上下文”会降低它的可重用性并导致更复杂的代码,最终成为天网并征服所有人类生命。以上是关于有没有更好的方法来处理快递中的错误?的主要内容,如果未能解决你的问题,请参考以下文章