Skip to content

Latest commit

 

History

History
64 lines (38 loc) · 4.4 KB

CSV-upload-issues.md

File metadata and controls

64 lines (38 loc) · 4.4 KB

CSV 업로드 및 오류 데이터 마킹

Requirements

  • 사용자가 csv 파일에 작성 후 파일 업로드를 통해 일괄 등록/수정할 수 있다.
  • 사용자가 작성한 내용에 오류가 있으면 모아서 에러와 함께 클라이언트에 반환하고, 화면에 붉은색으로 표시해서 쉽게 파악하고 수정할 수 있게 한다.
    • 예) 100건 입력 중 73건에 오류가 있다면 73건을 행 번호와 함께 반환하고, 건 별로 잘못된 컬럼의 값을 빨간색으로 표시할 수 있어야 한다.

시사점

일정 산정

  • CSV 일괄 등록/수정은 사용자가 직접 csv 파일에 직접 입력한 데이터를 서버에서 처리하므로, 화면에서의 validation 과정이 없어서 다양한 입력 오류가 발생할 수 있으며 서버 측 validation 이 굉장히 빡세다.
  • 다양한 오류 시나리오에 따른 테스트 작성양도 굉장히 많아질 수 있으므로 대략 두세 배 정도의 일정을 예상하는 것이 합리적이다.

예쁜 코드여 안녕

  • CSV 일괄 등록/수정이 아닌 일반적인 CUD의 경우 처리 과정 중 예외 발생 시 발생 위치에서 throw 하고 나중에 GlobalExceptionHandler 에서 처리하는 방식으로 깔끔하게 예외 처리를 구현할 수 있지만,
    • 오류 데이터를 모아서 나중에 처리하려면 발생한 예외를 비즈니스 로직에 따라 종류를 파악하고 catch 해서 적절한 처리를 해야 하므로,
      • 도메인 내에서 발생하는 예외를 추적에서 알아내야 하고, 예외에 대한 구체적인 정보가 커맨드 계층에 노출되며 예쁜 코드 작성은 물건너 간다.

오류 분류

  • 다양한 오류를 성격이나 처리 우선순위에 따라 잘 분류하지 않으면 구현이 굉장히 난잡하고 어려워 질 수 있다.
  • 다음과 같은 분류 기준을 적용하는 것을 권장한다.

파싱 전 오류

  • csv 파일 파싱 전에 처리하는 오류
    • csv 파일 파싱은 일반적으로 행 단위로 진행되며, 한 행 안에서 쉼표로 구분된 데이터를 해독하는 과정
  • 건수 제한, 파일 이름/확장자, 파일 형식 등과 관련된 오류
  • 파싱 전 오류 발생 즉시 에러 반환

파싱 오류

  • csv 파일 파싱 중에 발생하는 오류
  • 파싱 과정에서 오류가 발생하므로 파싱을 더 진행해서 오류 내용을 모으지 않고 파싱 오류 발생 즉시 행 번호와 행 내용을 예외에 저장하고 바로 던진다
  • 컬럼 갯수가 안 맞거나, 데이터 타입(숫자여야 하는데 문자 입력, Boolean이어야 하는데 숫자 입력, Enum 에 없는 값 등)

규격 오류

  • 값의 규격(정규표현식, min/max 등)에 맞지 않는 오류 등 사용자 입력 데이터만으로 판별할 수 있는 오류(즉 일반적으로 Validator에 의해 검출할 수 있는 오류)
  • 파싱 완료 이후에 검출되는 오류이므로 중간에 오류가 있더라도 csv 마지막행까지 검사하고 규격오류를 모두 모아서 행 번호와 행 내용(컬럼별 정상/비정상 표시 컬럼 추가 필요)을 예외에 저장해서 던진다

DB 오류

  • id 중복/없음 등 비즈니스 로직과 관련되어 DB 조회 후에 검출할 수 있는 오류
  • 여러 단계의 비즈니스 로직을 거치면서 발생할 수 있으며 모든 오류를 한 번에 모두 모으려면 예외 처리가 매우 불안정하게 되므로, 한 번에 모아 반환하지 않고 단계별로 처리
    • 여러 단계에서 발생하는 DB 오류가 포함돼 있다면 모든 DB 오류를 모두 모아서 한 번에 보여주지 않고 로직 흐름에 따라 발생 순서대로 DB 오류를 한 가지씩 반환
    • 동일한 단계에서 발생하는 한 가지 DB 오류가 여러 건에 걸쳐 발생한다면 이는 모두 모아서 한 번에 보여줄 수 있음

단계별 오류 처리

  • 파싱전오류가 있으면 다음 단계인 파싱오류 검증 단계에 진입하지 않고,
  • 파싱오류가 있으면 다음 단계인 규격오류 검증 단계에 진입하지 않고,
  • 규격오류가 있으면 다음 단계인 DB오류 검증 단계에 진입하지 않음

위와 같이 각자 다른 레이어에서 발생하는 오류를 구분 없이 모두 모아서 처리하려면 레이어 분리 구조도 유지할 수 없고 굉장히 많은 try-catch 처리로 인해 코드가 난장판이 될 수 있음