提问者:小点点

针对不同场景处理错误的NodeJS


我使用下面的函数,工作正常(我放了高水平的例子来演示这个问题),但是我有一些错误处理的问题

例如。

我想捕获所有函数的错误,但我想避免许多try catch块。。。

如果fn1fn2fn3返回任何错误,

诀窍是这样的

如果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语句。


共1个答案

匿名用户

我在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框架。