오늘의 Troubleshooting

아이템 시뮬레이터 과제

유효성 평가 미들웨어

  • 유효성 평가들 중, 겹치는 부분들을 묶어 미들웨어로 만드는게 편해보여 진행하려 한다!
  1. 유효성 평가 기능별 묶기

    • 비슷한 유효성 평가를 하는 기능들끼리 묶는건 좋아보인다만, 이를 어떻게 상세구분해줄 수 있는지가 고민이다..

    • 일단 기능적으로 묶인 router들을 이용해 1차로 구분을 해주고

    • 2차로 request의 [req.path] Propertie 를 사용해 구분해주면 될 것 같다!
      (추가로 method 구분도 필요하면 req.method 이용!)

     const path = req.path;
     // 회원가입 경우
     if (path === "/sign-up") {
         // 아이디 중복 확인
         const isExitUser = await prisma.accounts.findFirst({ where: { userId: id } })
         if (isExitUser) throw new Error("이미 존재하는 아이디입니다", { cause: 409 })
    
         // 비밀번호 확인이 없을 시
         if (!passwordCheck) throw new Error("비밀번호 확인용 <passwordCheck>를 입력해주세요", { cause: 400 })
    
         //비밀번호 확인과 일치하는지
         if (!(password === passwordCheck)) throw new Error("비밀번호가 일치하지 않습니다", { cause: 401 })
     // 로그인의 경우
     } else if (path === "/sign-in") {
         // 아이디가 없을 시
         const account = await prisma.accounts.findFirst({ where: { userId: id } })
         if (!account) throw new Error("존재하지 않는 아이디입니다.", { cause: 404 })
     }
    
  2. try catch로 status와 errorMessage 출력하기

    • 이 기능의 경우 message말고도 status도 같이 출력해야 하기에 error에 인수를 담을 수 있는지 찾아보았다.

    • 찾아보니 cause 라는 Error의 인수를 통해 전달가능할 것 같다!

     // 예시 try catch 문 
     try {
         const { itemCode } = req.params;
         const { body } = req;
         const { item_code } = body
    
         // 아이템 유효성 평가
         if (itemCode && Number.isInteger(+itemCode)) {
             // 아이템 존재 유무
             const item = await prisma.itemTable.findFirst({ where: { itemCode: +itemCode } })
             if (!item) throw new Error(`<item_code> ${itemCode}번의 아이템이 존재하지 않습니다`, { cause: 404 })
             req.item = item
         // 입력 타입이 다른 경우
         } else if (item_code && Number.isInteger(+item_code)) {
             const item = await prisma.itemTable.findFirst({ where: { itemCode: +item_code } })
             if (!item) throw new Error(`<item_code> ${item_code}번의 아이템이 존재하지 않습니다`, { cause: 404 })
             req.item = item
         }
         next()
         //던진 오류들 확인해서 반환
     } catch (err) {
         return res
             .status(err.cause)
             .json({ errorMessage: err.message })
     }
    
  3. 관련 API에 연결해주기

    • 원래 있던 유효성 평가를 지워주고 미들웨어를 가져와 실행시켜 주었다!
     import { signvaild } from '../middlewares/valid.middleware.js'
     const router = express.Router();
    
     // 회원가입 API
     router.post("/sign-up", signvaild, async (req, res, next) => {
         const { id, password} = req.body;
         //비밀번호 해쉬화
         const hashedPassword = await bycrpt.hash(password, 10)
         const account = await prisma.accounts.create({
             data: {
                 userId: id,
                 password: hashedPassword
             }
         })
         return res
             .status(201)
             .json({ message: "회원가입이 완료되었습니다", id: id })
     })
    
  • 기능들은 router 대신 유효성 평가하는 대상을 기준으로 분리를 마무리하였다.

유효성평가

오류/예외 처리 미들웨어

  • 에러메세지를 return res.status.json 으로 보내는 구문이 많은 것 같아 이를 try catch (err) 로 묶어주는 게 좋아보였다.

  • 미들웨어를 수정하는과정에서 오류들을 던지는 형식으로 바꿔서 이런 오류들을 디버깅하기 쉽게 설계해줬다.

app.use(function (err, req, res, next) {
    // 오류 확인
    console.error(err.stack);
    if(err.cause) res
        .status(err.cause)
        .json({errorMessage : err.message})
    else res.status(500).json({ errorMessage: "문제가 생겼습니다!관리자에게 문의해주세요."})
});

개선점 분석

  • 리팩토링 과정에서 많은 일들이 많았는데.. 이를 다 못적어서 아쉽다.

Reference

programmers
스파르타코딩클럽