<aside> 📖

학습 목표


1. 비동기 메서드의 반환 타입별 예외 전파 구조

비동기(@Async) 메서드는 호출 즉시 반환되고, 실제 로직은 별도의 스레드에서 수행됩니다.

이때 예외가 발생하면, 반환 타입에 따라 예외 전파 방식이 완전히 달라집니다.

반환 타입 예외 전파 여부 예외 확인 방법
void ❌ 호출자에게 전파되지 않음 AsyncUncaughtExceptionHandler 필요
Future<T> get() 호출 시 예외 확인 가능 ExecutionException 내부로 래핑되어 전달
CompletableFuture<T> ⭕ 체이닝 내에서 직접 처리 가능 exceptionally(), handle() 메서드 사용

다운로드 (21).svg


2. void 반환 메서드의 예외 처리

@Async 메서드가 void를 반환하면, 비동기 스레드에서 발생한 예외는 호출자에게 전달되지 않습니다.

즉, 메인 스레드는 예외를 감지할 방법이 없습니다.

2-1. 예제 코드

@Service
public class MailService {

    @Async
    public void sendEmail(String address) {
        System.out.println("[Async Thread] 이메일 발송 시작: " + address);
        if (address == null) {
            throw new IllegalArgumentException("이메일 주소가 null입니다.");
        }
        System.out.println("[Async Thread] 이메일 발송 완료");
    }
}

@RestController
@RequiredArgsConstructor
public class MailController {

    private final MailService mailService;

    @PostMapping("/send")
    public String sendMail(@RequestParam(required = false) String email) {
        mailService.sendEmail(email);  // 예외가 발생해도 여기서는 잡히지 않음
        System.out.println("[Main Thread] 요청 완료");
        return "메일 전송 요청 완료";
    }
}

✅ 실행 결과

[Main Thread] 요청 완료
[Async Thread] 이메일 발송 시작: null
Exception in thread "task-1" java.lang.IllegalArgumentException: 이메일 주소가 null입니다.

즉, 예외는 비동기 스레드(task-1) 에서 발생하지만, 호출자는 이를 감지할 방법이 없습니다.