Files
2nd/10_Wiki/Topics/Architecture/Replace Error Code with Exception (에러 코드를 예외로 바꾸기).md
T

4.3 KiB

Replace Error Code with Exception (에러 코드를 예외로 바꾸기)

📌 Brief Summary

'에러 코드를 예외로 바꾸기(Replace Error Code with Exception)'는 메서드가 오류를 나타내기 위해 특수한 값을 반환하던 방식을 예외(Exception)를 던지는 방식으로 변경하는 리팩토링 기법이다 [1]. 전통적인 프로그래밍에서는 반환 코드로 오류를 처리하여 정상적인 실행 흐름과 오류 처리 흐름이 뒤섞이는 문제가 있었으나, 예외를 사용하면 이 둘을 명확하게 분리할 수 있다 [2]. 결과적으로 프로그램의 구조가 단순해지고 코드의 가독성과 이해도가 크게 향상된다 [2].

📖 Core Content

  • 배경 및 동기: 오류를 발견한 프로그램의 특정 루틴이 그 오류를 어떻게 처리해야 할지 직접 결정할 수 없는 경우가 많다 [2]. 유닉스(Unix)나 C 기반 시스템과 같은 전통적인 환경에서는 루틴의 성공이나 실패를 호출자에게 알리기 위해 주로 반환 코드(Return code)를 사용해왔다 [2]. 그러나 자바(Java)를 비롯한 현대 프로그래밍 언어들은 예외 처리 메커니즘을 제공하므로, 에러 코드 대신 예외를 사용하여 정상적인 프로세스와 오류 처리 프로세스를 명확히 분리하는 것이 코드를 이해하기 쉽게 만든다 [2, 3].
  • 예외의 종류 결정: 리팩토링을 수행할 때 가장 먼저 발생한 예외가 검사 예외(Checked Exception)인지 비검사 예외(Unchecked Exception)인지 결정해야 한다 [4].
    • 호출자가 메서드를 호출하기 전에 상태를 검사해야 할 책임이 있는 상황에서 에러가 발생했다면, 이는 프로그래머의 버그이므로 비검사 예외(IllegalArgumentException 등)나 어서션(Assertion)을 사용해야 한다 [4-6].
    • 호출 전에 상태를 확인하는 것이 호출자의 책임이 아니라면, 메서드 시그니처에 검사 예외를 선언하여 호출자가 적절한 예외 처리(try-catch)를 하도록 유도해야 한다 [4, 5, 7].
  • 적용 절차 (Mechanics):
    1. 예외의 종류(검사/비검사)를 결정한 뒤, 비검사 예외라면 호출자들이 메서드 호출 전 적절한 검사를 수행하도록 수정한다 [4].
    2. 검사 예외라면 적절한 예외 클래스를 생성하거나 기존 예외를 사용하고, 호출자들이 try-catch 블록으로 메서드를 호출하도록 조정한다 [4, 7].
    3. 메서드 내부에서 에러 코드를 반환하던 부분을 예외를 던지는(throw) 코드로 변경하고, 메서드 시그니처를 이에 맞게 갱신한다 [8].
    4. 수정해야 할 호출자가 너무 많아 한 번에 변경하기 어렵다면, 예외를 던지는 새로운 중간 메서드를 생성한 뒤 기존 코드가 이를 호출하도록 임시로 변경하고, 호출자들을 하나씩 점진적으로 수정하는 방식을 취할 수 있다 [8-11].

⚖️ Trade-offs & Caveats

  • 예외 남용의 위험성: 에러 코드를 예외로 교체하는 것은 프로그램의 복잡성을 줄이는 훌륭한 방법이지만, 예외를 무분별하게 남용해서는 안 된다 [12]. 예외는 오직 예상치 못한 오류, 즉 '예외적인 동작'에만 국한해서 사용해야 한다 [12].
  • 조건 검사를 대체할 수 없음: 예외가 일반적인 조건문(Conditional test)을 대체하는 용도로 쓰여서는 안 된다 [12]. 만약 호출자가 작업을 수행하기 전에 조건이 유효한지 합리적으로 확인할 수 있는 상황이라면, 예외를 던지게 두는 대신 호출자가 사전에 테스트(검사)하도록 강제해야 한다 [12]. 만약 조건 검사를 무시하고 예외를 남용하고 있다면, 반대로 '예외를 테스트로 바꾸기(Replace Exception with Test)' 리팩토링을 고려해야 한다 [3, 12].
  • 대규모 변경의 부담: 검사 예외(Checked Exception)를 새롭게 적용할 경우, 해당 메서드를 호출하는 모든 코드와 호출되는 루틴을 동시에 수정해야 하므로 컴파일러 에러가 유발될 수 있다 [9]. 시스템 규모가 클 경우 한 번에 적용하기에는 리스크가 크고 작업량이 과도해질 수 있다는 제약이 따른다 [9].

Last updated: 2026-05-03