Skip to content

Latest commit

 

History

History
226 lines (172 loc) · 5.79 KB

File metadata and controls

226 lines (172 loc) · 5.79 KB

Error Handling

Contents

  1. Different Types of Errors
  2. Handling Errors

1. Types of Errors

  • 에러가 발생했다고 무조건 app 이 멈출 필요는 없다
  • 적절하게 에러를 처리하면 된다.

에러 종류

  1. Technical / Network Errors
    • eg. MongoDB 서버 다운
    • 해결 방법 : 유저에게 에러 페이지를 보여준다
  2. '예상된 에러'
    • eg. 파일을 읽을 수 없거나 데이터베이스에서 파일을 읽을 수 없음
    • 해결 방법 : 유저에게 알리고 가능하면 다시 시도하게 유도한다.
  3. Bugs / Logical 에러
    • eg. 유저 객체가 존재하지 않을 때 사용하려고 한다.
    • 해결 방법 : 개발중에 고친다

2. Handling Errors

  • 전반적인 에러 처리 흐름

![Handling Errors](C:\Users\kooks\Desktop\StudyInGit\AllaboutNode\Img\Handling Errors.png)

3. 프로젝트에 적용하기

커스텀 에러 처리 보완하기

  1. 시작하기 전에 node.js 의 에러 핸들링 기능 살펴보기

    • node.js는 throw new Error()를 사용해서 에러 처리가 가능하다.

      const sum = (a, b) => {
        if (a && b) {
          return a + b;
        }
        throw new Error('Invalid arguments');
      };
      console.log(sum(1));
      
      /*C:\Users\kooks\Desktop\StudyInGit\AllaboutNode\Project1-2\test.js:5
        throw new Error('Invalid arguments');
        ^
      
      Error: Invalid arguments
          at sum (C:\Users\kooks\Desktop\StudyInGit\AllaboutNode\Project1-2\test.js:5:9)
          at Object.<anonymous> (C:\Users\kooks\Desktop\StudyInGit\AllaboutNode\Project1-2\test.js:7:13)
          at Module._compile (internal/modules/cjs/loader.js:776:30)
          ...
          */

      위와 같이 에러를 만들 수 있다.

    • try catch 이용해서 에러 처리하기

      ...
      try {
        console.log(sum(1));
      } catch (erorr) {
        console.log('Error occurred!');
      }
      
      console.log('Continue!');

      try catch 를 사용하게 되면 코드 실행을 멈추지 않고 계속해서 실행한다. 따라서 'Continue!' 라는 로그를 볼 수 있다.

  2. app.js 아래 코드에 있는 catch 문은 기술적 오류만 잡아 낼 수 있으므로 데이터베이스에 user가 존재 하지 않을 때 오류를 걸러낼 수 없다. 이를 수정하기.

    app.use(
      session({
        secret: 'my secret',
        resave: false,
        saveUninitialized: false,
        store: store
      })
    );
    app.use(csrfProtection);
    app.use(flash());
    
    app.use((req, res, next) => {
      if (!req.session.user) {
        return next();
      }
      User.findById(req.session.user._id)
        .then(user => {
    	// user가 존재하지 않으면 아래 코드 건너 뛰기
          if (!user) {
            return next();
          }
          req.user = user;
          next();
        })
    	.catch(err => {
          throw new Error(err);
        });
    });
  3. controllers/admin.js postAddProduct 수정하기

    MongoDB에 문제가 발생하면 전체 app이 멈춘다. 이 문제를 해결하기 위해 catch 구문 수정하기

    exports.postAddProduct = (req, res, next) => {
      const title = req.body.title;
      const imageUrl = req.body.imageUrl;
      const price = req.body.price;
      const description = req.body.description;
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(422).render('admin/edit-product', {
          pageTitle: 'Add Product',
          path: '/admin/add-product',
          editing: false,
          hasError: true,
          product: {
            title: title,
            imageUrl: imageUrl,
            price: price,
            description: description
          },
          errorMessage: errors.array()[0].msg
        });
      }
      const product = new Product({
        title: title,
        price: price,
        description: description,
        imageUrl: imageUrl,
        userId: req.user
      });
      product
        .save()
        .then(result => {
          // console.log(result);
          console.log('Created Product');
          res.redirect('/admin/products');
        })
        .catch(err => {
          res.redirect('/500')
        });
    };
  4. controllers/error.js get500 추가하기

    exports.get500 = (req, res, next) => {
      res.status(500).render('500', {
        pageTitle: '에러 ㅠㅠ',
        path: '/500',
        isAuthenticated: req.session.isLoggedIn
      });
    };
  5. app.js 500 에러 페이지 라우팅 하기

    app.use('/500', errorController.get500);

Express.js 오류 처리 미들웨어 사용

익스프레스는 위에서 부타 아래로 실행된다는 것을 기억해야 한다. 오류 미들 웨어을 다른 모든 미들웨어의 뒤에 정의해야 한다. 그렇지 않으면 오류 처리기는 호출되지 않는다.

  1. app.js 에러 처리 미들웨어 작성하기

    // 보통 여기 미들웨어 까지 올 수 없지만 4개의 인자를 넣어주면 바로
    // 여기로 도달하게 된다.
    app.use((error, req, res, next) => {
      res.redirect('/500');
    });
  2. 각 catch 블락에 에러 코드 넣기

        .catch(err => {
          // 500 서버사이드 오류 추가해주기
          // res.redirect('/500');
          const error = new Error(err);
          error.httpStatusCode = 500;
          // 다른 모든 미들웨어를 건너뛰고 error 처리 미들웨어로 이동한다.
          return next(error);
        });

Errors & Http Response Codes

  • 200 번대 : 성공
  • 300 번대 : Redirect
  • 400 번대 : Client - side Error
  • 500 번대 : Server - side Error