我使用下面的函数,工作正常(我放了高水平的例子来演示这个问题),但是我有一些错误处理的问题
例如。
我想捕获所有函数的错误,但我想避免许多try catch块。。。
如果fn1
或fn2
或fn3
返回任何错误,
诀窍是这样的
如果fn2(bar)
没有特定的属性(请参阅if),返回uniq错误某些错误uniq!
,而不是一般错误。。。
async function GetUsers() {
try {
const aaa = await fn1(foo)
const bbb = await fn2(bar)
if (! bbb.data.url) {
throw new Error(
'Something went wrong uniq!!! ’,
);
}
const ccc = await fn3(foo2)
….
return url;
} catch (e) {
throw new Error(
"Something went wrong in general",
);
}
}
现在,如果我抛出uniq错误,它会抓住它,然后吞噬一般…。
如果有更好的方法来处理这些错误,请告诉我
在NodeJs中有没有更干净的方法来做这件事?
我不想对catch等中的消息使用if语句。
我在utils/catchasync.js
中有我的代码,它的实现很简单
module.exports = fn => {
return (req, res, next) => {
fn(req, res, next).catch(next);
};
};
const catchAsync = require('../utils/catchAsync');
exports.getRelatedProducts = catchAsync(async (req, res, next) => {
// your code, access to database
res.status(200).json({
status: 'success',
});
});
const globalErrorHandler = require('./controllers/errorController');
app.use(globalErrorHandler);
我从网上找到的多个解决方案中定制了我的解决方案,它是围绕MongoDB,Mongoose和它们的错误定制的。 我还有关于错误对象的简单错误实现。
const AppError = require('./../utils/appError');
const handleCastErrorDB = err => {
const message = `Invalid value message...`;
return new AppError(message, 400);
};
const handleDuplicateFieldsDB = () => {
const message = `Already exists message..`;
return new AppError(message, 400);
};
const handleValidationErrorDB = err => {
const errors = Object.values(err.errors).map(el => el.message);
const message = `${errors.join('. ')}`;
return new AppError(message, 400);
};
const handleJWTError = () =>
new AppError('Invalid token message...', 401);
const handleJWTExpiredError = () =>
new AppError('Session expired message...', 401);
const sendDebugError = (err, req, res) => {
if (req.originalUrl.startsWith('/api')) {
return res.status(err.statusCode).json({
status: err.status,
error: err,
message: err.message,
stack: err.stack
});
}
};
const sendNormalError = (err, _, res) => {
if (err.isOperational) {
return res.status(err.statusCode).json({
status: err.status,
message: err.message
});
}
if (err.type === 'entity.parse.failed') {
return res.status(400).json({
status: 'fail',
message: 'Wrong data format message..',
});
}
return res.status(500).json({
status: 'error',
message: 'Internal error message..'
});
};
module.exports = (err, req, res, _) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
if (process.env.NODE_ENV === 'development') {
sendDebugError(err, req, res);
} else {
let error = { ...err };
error.message = err.message;
if (error.name === 'CastError') error = handleCastErrorDB(error);
if (error.code === 11000) error = handleDuplicateFieldsDB();
if (error.name === 'ValidationError')
error = handleValidationErrorDB(error);
if (error.name === 'JsonWebTokenError') error = handleJWTError();
if (error.name === 'TokenExpiredError') error = handleJWTExpiredError();
sendNormalError(error, req, res);
}
};
这个解决方案主要来自于这个Gitlab回购协议。 和Udemy课程,用于此回购所连接的Node.js框架。