1 minute read


study

msa

설계적 고민. validation 및 에러 처리에 대해, msa를 사용할 때 여러 다른 종류의 프레임워크를 사용하면 다른 형태의 validation result/error를 얻게 된다.. 그렇게 되면, 프론트엔드는 30가지 다른 형태의 에러 응답들을 처리해야 하게 될 수도 있는 것이다. 게다가, 프론트엔드 개발자가 백엔드 응답 형태를 신경써서 구현하게 되는 것 자체도 문제다.

이 문제는 비단 validation만의 문제가 아니라, 조금이라도 opinionated된 툴을 사용할 때의 문제점이라고 생각된다. 강사는 이 문제를 다시 응답을 normalize함으로써 해결해야 한다고 한다.

그러면 validation이 추가될 경우 에러 응답 정규화 시나리오는 다음과 같이 된다:

  1. 정상 형태 요청 - validation 통괴 - 비즈니스 에러 (중복 이메일 등) -> 정규화
  2. 비정상 형태 요청 - validation 에러 -> 정규화

좀더 크게 보자면 다음 두 가지 항목을 신경써야 (driving force) 한다.

  1. 모든 서버의 모든 응답에서, 어디에서 잘못되었든 일관적 응답을 보내주어야 한다.
  2. 어디서 잘못되었든 처리해야 한다.

express에서 4개 파라미터를 가진 미들웨어는 아래와 같이 에러 핸들링 미들웨어이다.

app.use(function (err, req, res, next) => {
  ...
})

rust

결국 map_err를 사용하지 않고, 커스텀 from으로 ?를 사용할 때 자동 캐스팅 되도록 하여 해결했다.

...
impl From<ParseIntError> for ParsePosNonzeroError {
    fn from(err: ParseIntError) -> ParsePosNonzeroError {
        ParsePosNonzeroError::ParseInt(err)
    }
}

impl From<CreationError> for ParsePosNonzeroError {
    fn from(err: CreationError) -> ParsePosNonzeroError {
        ParsePosNonzeroError::Creation(err)
    }
}

fn parse_pos_nonzero(s: &str) -> Result<PositiveNonzeroInteger, ParsePosNonzeroError> {
    // TODO: change this to return an appropriate error instead of panicking
    // when `parse()` returns an error.
    let x = s.parse::<i64>()?;
    PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation)
}
...

다른 방법으로 예를 들어 match를 사용했을 때 어떻게 에러 일때의 케이스를 작성해야 하는 것인지 모르겠다.


Comments