Express.js에서 오류를 처리하는 간단한 방법

Express에서 오류를 처리하는 여러 가지 방법이 있습니다. 이를 수행하는 일반적인 방법은 기본 익스프레스 미들웨어를 사용하는 것입니다.

app.use(function(err, req, res, next) {
    console.error(err.stack);
    res.status(500).send('Something broke!');
}


또 다른 방법은 컨트롤러 내부의 오류를 처리하는 것입니다.

router.get("/users", async (req, res) => {
    try {
        const users = await User.getAll();
    }
    catch(err) {
        return res.status(500).json({
            message: "Something broke!",
        });
    }

    res.status(200).json({
        message: "success",
        data: users,
    });
})


이러한 처리 방식은 코드를 깨끗하게 유지하는 데 몇 가지 문제를 일으킬 수 있습니다. 이 문제는 컨트롤러가 많거나 다음 예제와 같은 일부 기능이 있을 때 더욱 분명해집니다.

router.get("/profile", async (req, res) => {
    try {
        const {username} = await User.auth();
        const preferences = await User.getPreferences(username);
    }
    catch(err) {
        if(err instance of AuthError) {
            return res.status(401).json({
                message: "Unauthorized",
            });
        }
        else {
            return res.status(500).json({
                message: "Something Broke!",
            });
        }
    }

    res.status(200).json({
        message: "success",
        data: users,
    });
});



try/catch 블록으로 인해 코드의 가독성이 떨어지는 것을 볼 수 있습니다. 유사한 함수를 호출해야 하는 다른 경로가 있는 경우 코드를 반복하게 되므로 이상적이지 않습니다.

간단한 해결책.



이 문제에 대한 간단한 해결책은 컨트롤러 기능이 포함된 래퍼를 사용하고 래퍼가 예외를 처리하도록 하는 것입니다.
래퍼는 다음과 같습니다.

const errorHandlerWrapper = (promiseCallBack) => {
  return async (req, res, next) => {
    try {
      await promiseCallBack(req, res, next);
    } catch (err) {
      if (err instanceof AuthError) {
        res.status(401).json({
          message: "Unauthorized",
        });
      } 
      else {
        console.log(err);
        res.status(500).json({
          message: "Something Broke!",
        });
      }
    }
  };
};

errorHandlerWrapper 콜백으로 사용되는 컨트롤러를 받습니다. 그런 다음 try/catch 블록 내에서 콜백을 실행하는 함수를 반환합니다.

그런 식으로 컨트롤러 외부에서 오류 처리를 위임합니다.

코드를 리팩토링하면 다음과 같습니다.

router.get("/profile", errorHandlerWrapper(async (req, res) => {
    const {username} = await User.auth();
    const preferences = await User.getPreferences(username);

    res.status(200).json({
        message: "success",
        data: users,
    });
}));


코드가 어떻게 줄어들고 가독성이 높아졌는지 확인하십시오. 이 모든 동안 우리는 여전히 오류를 효과적으로 처리하고 있습니다.

결론



경로 컨트롤러를 읽을 수 있도록 유지하는 것이 중요합니다. 코드가 커지기 시작하면 컨트롤러를 깨끗하게 유지하는 것이 어려울 수 있습니다. 반복되는 코드 블록에 대한 대안을 구현하는 것이 그것을 마주하는 첫 번째 단계입니다.

컨트롤러 내에서 예외를 처리하는 다른 방법을 알고 있다면 댓글로 알려주세요✌

좋은 웹페이지 즐겨찾기