2025-10-10

1일 1아티클

LY

Error Handling

복구 가능 수준

  1. 기본값
    • 호출자가 에러 발생 여부 파악 필요 X
    • ex. "", 0(가산값), 1(계수), Int.MIN_VALUE, [], null 객체 패턴
  2. 단순 도메인 에러
    • 에러 발생 사실 인지 필요, 내용 파악 필요 X
    • 조기 반환 적용
    • ex. null, nil, undefined, Optional, Maybe, false
  3. 에러값을 포함한 sum type이나 nullable 에러값 (또는 다중 반환값(Go, Python))
    • 정상일 때와 에러일 때 각각 다른 값이 필요한 경우
    • 호출자가 에러 유형에 따라 다르게 처리 필요 시 유용
    • ex. Either, Result, sealed class, 연관값, nullable 에러값
  4. 확인된 예외
    • Java의 경우 Exception에 스택 정보 등 많은 정보 포함
    • ex. Java의 Exception, Swift의 Error
  5. 확인되지 않은 예외
    • 처리 시스템 에러나 로직 에러 등 대부분 복구 불가능한 에러에 사용
    • 호출자가 에러 발생 가능성 자체를 간과할 수 있는 예외
    • ex. Java의 RuntimeException
  6. 캐치 불가능한 에러
    • 확인되지 않은 예외와 유사하나, 보다 엄격한 빠른 실패(fail first) 구현
    • ex. Swift의 fatalError()

한 번 엎지른 <error>는 다시 주워 담지 못한다


  /**
  * Parses the given "FOO" data string then returns the parsed integer by wrapping with
  * [FooParseResult].
  *
  * The expected format is: "foo:(1-6 digit non-negative integer)".
  * For example, "foo:00" and "foo:123456" are valid while "foo : 1", "foo,2", "foo:-1" are not.
  * 
  * This throws [IllegalArgumentException] if the given text format is invalid.
  */
  @Throws(IllegalArgumentException::class)
  fun parseFooValue(inputText: String): FooParseResult {
      val matchResult = FOO_FORMAT_REGEX.matchEntire(inputText)
      requireNotNull(matchResult) // Throws if `inputText` format is invalid

      val fooIntValue = matchResult.groupValues.getOrNull(1)?.toIntOrNull()
      return if (fooIntValue != null) {
          FooParseResult.Success(fooIntValue)
      } else {
          FooParseResult.InvalidRegexError
      }
  }

  /** Result model of parsing "FOO" integer from string value. */
  sealed class FooParseResult {
      /** A result representing "FOO" data is correctly parsed as an integer. */
      class Success(val value: Int) : FooParseResult()

      /** An error result representing the parsing regex implementation is incorrect. */
      object InvalidRegexError : FooParseResult()
  }

  private val FOO_FORMAT_REGEX: Regex = """foo:(\d{1,6})""".toRegex()

  1. 인수로 입력된 문자열 형식 오류
    • ‘잘못된 인수가 입력되는 것은 흔하다’ 라는 전제하에 에러 처리 구현 필요
    • IllegalArgumentException 으로 표현되어 있는데, 이 경우 catch X
  2. 정규표현식 구현 실수
    • 로직 에러
    • sealed 객체로 표현되어 호출자가 처리하도록 강제 중
    • 에러 처리 방법과 에러 표현 방법이 다름!

개선 방안

  • 잘못된 입력 → null 반환
  • 정규 표현식 구현 실수 → 확인되지 않은 예외 사용
    • 문자열 그룹 조회 시 getOrNullget ([]) 사용
    • toIntOrNulltoInt 사용

에러의 복구 정도에 따라 적절한 에러 표현 방법 사용할 것!

오늘 배운 것

  1. 조인
  2. 서브쿼리 활용

내일 할 일

  1. 바이브 프로젝트 API 개발

참고자료

  • [코드 품질 개선 기법 1편: 한 번 엎지른 는 다시 주워 담지 못한다](https://techblog.lycorp.co.jp/ko/techniques-for-improving-code-quality-1)

results matching ""

    No results matching ""