Project 3 - Richmaker 6

Junjii·2023년 10월 5일
0

Project3

목록 보기
6/6

<Project 3 - Richmaker >
기간 : 3주
팀원 : 프론트 2명 (PM) / 백엔드 5명
필수 구현 사항 : 로그인, 회원가입, 테스트 코드, 메인페이지, 공동관리 페이지, 마이데이터(구현), 거래내역 리스트

const postTransactions = async (userID, data) => {
  const CI = await getUserCI(userID);

  await Promise.all(
    data.map(async (obj) => {
      let providerID = obj.providerID;
      let financeNumber = obj.financeNumber;
      let financeName = obj.financeName;

      const userFinancesID = await providerDao.insertUserFinances(
        userID,
        providerID,
        financeNumber,
        financeName
      );

      const options = {
        method: "POST",
        uri: "http://10.58.52.75:3000/mydata",
        body: {
          CI: CI,
          userFinancesId: userFinancesID,
          providerID: providerID,
          financeNumber: financeNumber,
        },
        json: true,
        resolveWithFullResponse: false,
        simple: false,
      };

      

      const responseFromAccountTransaction = await request(options);

      if (responseFromAccountTransaction.message == "NO_RECORDS") {
        const error = new Error("NO_RECORDS");
        error.statusCode = 403;
        throw error;
      }



      const res = decrypt(responseFromAccountTransaction.data);
      const response = res[0];

      response.map(async (obj) => {
        let amount = obj.amount;
        let transactionNote = obj.transactionNote;
        let categoryID = obj.categoryID;
        let isMonthly = obj.isMonthly;
        let createdAT = obj.createdAT;

        await providerDao.insertTransactions(
          userFinancesID,
          amount,
          transactionNote,
          categoryID,
          isMonthly,
          createdAT
        );
      });
    })
  );
};

< 문제 발생 >

저번 글에서 작성했던 API 중 4번째 API 를 작성하던 중 문제가 발생했다.

상황설명 : 고객이 선택한 계좌번호/ 카드번호를 백엔드 서버로 받아오면 선택한 금융의 각각의 고유번호(userFinanceId)를 구한 후 계좌/카드 마다 한번씩 거래내역을 마이데이터로 요청한 후 저장한다.

예를 들어 고객이 최종적으로 4개의 금융을 선택했다면 위의 작업을 4번 해야하는 상황이다.

상황 당시 나는 반복적으로 일을 처리해야겠다 생각했고 프론트에서는 데이터를
[ { }, { }, { },....... ] 이렇게 배열 안에 객체 형식으로 전달해준다고 했다. 그래서 map 을 활용해서 만들어야겠다 라고 생각했다.

그러나 여기서 문제가 발생하는데

<문제 분석>

map 을 사용해서 반복적인 작업을 처리하며 거기서 발생하는 에러를 controller 에서 error 를 캐치하여 errorstatus 로 사용하고 싶었으나 error 를 캐치 하지 못하는 상황이 생겼다.

외부 api 에서 “NO_RECORDS” 라고 메세지를 보내줄때
나는 if(response.message == “NO_RECORDS”) 일 경우

error 를 선언하여 “NO_RECORDS” message 를 전달하고 error status code 를 400 으로 지정하여 throw 를 하고 싶었다. 그러나 controller에서 error 를 전혀 잡지 못했다.

<문제 파악>

그래서 에러를 어느 부분에서 error를 캐치를 못하는 것인지 파악하기 위해 console.log() 를 찍어 추적하기 시작했고 error 메세지를 if() 문 안에서 받아내는 것까지는 가능했으나 controller 로 throw 를 하지 못하는 상황이였다.

<문제 해결>

결론은 promise.all() 로 map을 사용했던 부분을 모두 감쌌더니 해결이 되었다. 원인은 반복문의 동기 비동기에 대한 이해가 부족했다.
먼저 반복문마다의 특성을 처음 알았다. 결과값만 맞으면 된다고 생각했지만 각 반복문마다 결과를 만들어내기까지의 특성이 다르다.

나의 코드에 map 을 사용한 이유는 배열 안의 여러가지의 객체를 각각 사용해야하기 때문이였다. 그런데 map 의 특성상 동기 방식이기 때문에 던지지 못하는 것이였다. 그래서 그 전체를 promise.all 안에 넣어줌으로써 비동기적으로 흘러가게 해주며 하나라도 에러가 뜬다면 그 후에 작업은 진행하지 않게 해준다.
그래서 해결 전의 코드에 async 를 사용하더라도 작용하지 않고 흘러가던 것이였다.

따라서 각각의 반복문이 단순히 배열의 상황이냐 아니냐의 문제보다 더 심도 깊게 이해하여 비동기 동기적인처리부터 배열의 재구성이냐 단순히 배열의 인덱스를 수정하느냐 등등 각각의 기능과 역할을 제대로 파악하고 사용해야 하는 것이다.

0개의 댓글