공공부하자개발 · 영어 학습 노트
자바
중급객체지향과 코어 라이브러리0/9 완료
  • 01상속, 다형성, 오버라이딩
  • 02추상 클래스 vs 인터페이스
  • 03예외 처리
  • 04java.lang 심화
  • 05컬렉션 프레임워크 딥다이브
  • 06메서드 활용 패턴 (중급)
  • 07Object 메서드와 비교
  • 08java.time 실무 날짜 계산
  • 09HTTP 와 JSON 기초
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 중급 › 03 / 9

예외 처리

섹션 7진행 0 / 9
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

5. 자주 하는 실수 (Tip)

❌ 실수 1: 빈 catch로 예외 삼키기

java
try {
    orderRepository.save(order);
} catch (Exception e) {
    // 나중에 처리
}
sendConfirmationEmail(order);   // 저장 실패했는데 확인 메일 발송

저장이 실패해도 아무 일 없다는 듯 진행된다. 고객은 확인 메일을 받았는데 주문이 없다.

java
try {
    orderRepository.save(order);
} catch (DataAccessException e) {
    throw new OrderSaveFailedException(order.id(), e);   // 처리 못 하면 전파
}
sendConfirmationEmail(order);

정말로 무시해도 되는 예외라면(예: 선택적 캐시 갱신 실패) 주석으로 왜 무시해도 되는지 남기고 최소한 로그를 찍는다.

❌ 실수 2: cause 없이 예외 전환

java
catch (SQLException e) {
    throw new DataAccessException("DB 오류: " + e.getMessage());   // 스택트레이스 손실
}

메시지만 복사하면 어느 SQL, 어느 줄에서 났는지 알 수 없다. 장애 원인 분석이 불가능해진다.

java
catch (SQLException e) {
    throw new DataAccessException("DB 오류: orderId=" + id, e);   // cause 체이닝
}

❌ 실수 3: catch 순서 오류

java
try { ... }
catch (Exception e) { ... }            // 부모를 먼저
catch (IOException e) { ... }          // 컴파일 에러: 이미 위에서 잡혀 도달 불가
java
try { ... }
catch (FileNotFoundException e) { ... }   // 가장 구체적
catch (IOException e) { ... }
catch (Exception e) { ... }               // 가장 일반적

❌ 실수 4: 자원을 수동으로 닫다가 누수

java
FileInputStream in = new FileInputStream("a.txt");
byte[] data = in.readAllBytes();       // 여기서 예외 나면 close() 안 됨
in.close();
java
try (FileInputStream in = new FileInputStream("a.txt")) {
    byte[] data = in.readAllBytes();   // 예외가 나도 close() 보장
}

❌ 실수 5: 정상 흐름을 예외로 처리

java
Integer parse(String s) {
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {
        return null;                    // "숫자가 아닐 수 있음"은 정상 케이스인데 예외로 처리
    }
}

입력의 절반이 숫자가 아니라면 절반의 호출마다 스택트레이스를 캡처한다. 예측 가능한 케이스는 사전 검사하거나 Optional로 표현한다.

java
Optional<Integer> parse(String s) {
    if (s == null || !s.matches("-?\\d+")) return Optional.empty();
    return Optional.of(Integer.parseInt(s));
}

❌ 실수 6: throws Exception으로 뭉뚱그리기

java
void process() throws Exception { ... }   // 무엇이 실패하는지 아무 정보 없음

호출자도 catch (Exception e)를 쓸 수밖에 없고, 그러면 NPE 같은 버그까지 함께 삼킨다.

java
void process() throws IOException, InterruptedException { ... }   // 구체적으로
// 또는 unchecked 비즈니스 예외로 전환해 throws 자체를 제거
자주 하는 실수 (Tip)
  • ❌ 실수 1: 빈 catch로 예외 삼키기
  • ❌ 실수 2: cause 없이 예외 전환
  • ❌ 실수 3: catch 순서 오류
  • ❌ 실수 4: 자원을 수동으로 닫다가 누수
  • ❌ 실수 5: 정상 흐름을 예외로 처리
  • ❌ 실수 6: throws Exception으로 뭉뚱그리기
이전 섹션4 응용 변형 예제5 / 7다음 섹션6 연습 문제