728x90
doOnError와 onErrorResume은 Spring WebFlux의 WebClient와 같은 반응형 프로그래밍에서 오류를 다루는 데 사용되는 메서드인데, 목적과 동작 방식에서 차이가 있어서 간단히 소개해보려고 함
doOnError
- 로깅, 메트릭 기록, 알림 전송 등과 같이 오류가 발생했을 때 오류를 처리하지 않지만 발생했다는 사실만 감지하여 추가 작업을 수행할 수 있는 매서드
- 즉, 오류를 처리하거나 복구하지 않고, 오류가 발생했다는 사실을 감지해 추가 작업을 수행하고 이후 오류는 스트림 아래로 그대로 전달
- 반환 값은 없으며 보통 에러 로그를 남기기 위해 사용됨
doOnError 예시 코드
WebClient webClient = WebClient.create("https://sg-moomin.tistory.com");
String exceptionDefaultMessage = "exception occurred to";
webClient.get()
.uri("/contents")
.retrieve()
.bodyToMono(String.class)
.doOnError(throwable -> System.err.println(exceptionDefaultMessage + throwable.getMessage()))
.subscribe(
...
);
doOnError 사용 목적
- 오류를 기록하거나 모니터링하고 싶을 경우나 단순 감지만 해도 문제가 없는 경우
onErrorResume
- 오류가 발생했을 때 오류에 대해 해결하고 새로운 스트림(Mono, Flux)을 제공하여 정상적으로 Flow를 흘림
- 즉, 오류 전파가 되지 않는다는 의미이며 더 이상 아래 Flow로 오류를 전달하지 않음
- 예외 처리를 하지 않아도 되는 상황이지만 로그를 남겨야할 경우 적합하다고 볼 수 있음
onErrorResume 예시 코드
WebClient webClient = WebClient.create("https://sg-moomin.tistory.com");
String exceptionDefaultMessage = "exception occurred to";
String newStream = "onErrorResume By new Mono";
webClient.get()
.uri("/data")
.retrieve()
.bodyToMono(String.class)
.onErrorResume(throwable -> {
System.err.println(exceptionDefaultMessage + throwable.getMessage());
// 새로운 스트림을 생성
return Mono.just(newStream);
})
.subscribe(
...
);
- API 호출 실패 시 exceptionDefaultMessage를 출력하고 새로운 스트림(newStream)을 반환한다.
- 이에 따라 error 전파가 되지 않으며, 만약 subscribe에서 error 람다를 호출하더라도 error가 실행되지 않는다.
- 현재는 Mono에 기본값을 넣어뒀는데 이는 예외가 발생하더라도 후속 로직을 추가해줬다고 볼 수 있으며 후속 로직 없이 예외 자체를 무시하고 싶을 경우에는 Mono.Empty를 반환하면 됨
onErrorResume 사용 목적
- 오류가 발생했을 때 대체 로직으로 Flow를 수행하고 싶을 때나 사용자에게 오류 상황을 노출시키지 않고 싶을 때 사용
doOnError vs onErrorResume 차이점 정리
doOnError | onErrorResume | |
목적 | 부수 효과 실행 (로깅 등) | 오류 복구 및 대체 값 제공 |
오류 전파 | 오류를 그대로 전달 | 오류를 잡고 전파 중단 |
스트림 변경 | 변경 없음 | 새로운 Mono/Flux로 대체 |
반환값 | 없음 | 새로운 Mono/Flux |
사용 시나리오 | 오류 관찰 및 기록 | 오류 해결 및 스트림 지속 |
기타
1) doOnError와 onErrorResume을 같이 쓸수도 있음?
doOnError와 onErrorResume을 둘다 함께 사용할 수 있는데, 굳이 두개를 같이 쓰는건 비효율적이라고 생각함
그 이유는 onErrorResume에서도 로깅과 같은 부분은 처리가 가능하기 때문에 불필요한 중복 로직이 들어갈 수도 있고
단순 로깅 혹은 오류 전파 중단을 위해 사용하는거라면 함께 사용하는건 비추임
오히려 onErrorResume 단일으로 사용하는게 조금 더 효율적이지 않을까 하는게 주관적인 의견임
- 오류 전파를 하고 싶다면 같이 써야하겠지만. 새로운 Stream을 통해 결과를 반환하고 서비스 로직에서 후처리해도 무관하지 않을까 싶음
728x90
'Programing > Java & Spring' 카테고리의 다른 글
세무민의 코딩일기 : Spring WebClient 내장 Thread에 대해 알아보자 (0) | 2025.04.06 |
---|---|
세무민의 코딩일기 : Spring WebClient에 대해 알아보자 (1) | 2025.03.10 |
[Spring] QueryDsl, java17 Q파일 생성 안되는 이슈 해결 (0) | 2025.01.24 |
[JPA&QueryDSL] QueryDsl이란 무엇인가? (4) | 2024.11.24 |
[Spring] 정의되지 않은 요청 파라미터에 대한 유효성 검증 및 Jackson 과 @EnableWebMvc의 관계성 (2) | 2024.11.12 |