Reputation: 1343
As there are many methods like onErrorReturn
, onErrorResume
etc, so which one's the right one to use in order to handle errors in Reactive Spring WebFlux for mono and flux?
Upvotes: 25
Views: 39383
Reputation: 1343
Sharing my knowledge:
In total there are six methods provided to handle error, five discussed below:
onErrorReturn: return fallback value for entire stream (mono/flux). E.g. if there’s a flux of 10 elements, and error happens on element 3, then rest 4,5,6… won’t be executed, instead the fallback value will be considered.
onErrorResume: return fallback value in terms on Mono/Flux for entire stream (mono/flux). E.g. if there’s a flux of 10 elements, and error happens on element 3, then rest 4,5,6… won’t be executed, instead the fallback value will be considered.
onErrorContinue: consumes (error,data) and does NOT split it over. It considers the consumer for the error elements, and leave the downstream chain as it for good elements. E.g. if there’s a flux of 10 elements, and error happens on element 3, then all elements (1 to 10) except 3 will have normal execution, but element 3 will have a different execution as mentioned in the consumer of onErrorContinue
doOnError: consumes error and spills it over. Stops execution for further elements in stream.
onErrorMap: cast one error into another. Stops execution for further elements in stream.
All these five methods come in 3 variants,
Examples:
@Test
public void onErrorReturnDirectly_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorReturn(4)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void onErrorReturnIfArithmeticException_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorReturn(ArithmeticException.class, 4)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void onErrorReturnIfPredicatePasses_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorReturn(error -> error instanceof ArithmeticException, 4)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void onErrorResume_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorResume(error -> Mono.just(4))
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void onErrorResumeIfArithmeticException_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorResume(
ArithmeticException.class,
error -> Mono.just(4)
)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void onErrorResumeIfPredicatePasses_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorResume(
error -> error instanceof ArithmeticException,
error -> Mono.just(4)
)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void onErrorContinue_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorContinue((error, obj) -> log.info("error:[{}], obj:[{}]", error, obj ))
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void onErrorContinueIfArithmeticException_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorContinue(
ArithmeticException.class,
(error, obj) -> log.info("error:[{}], obj:[{}]", error, obj )
)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void onErrorContinueIfPredicatePasses_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorContinue(
error -> error instanceof ArithmeticException,
(error, obj) -> log.info("error:[{}], obj:[{}]", error, obj )
)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void doOnError_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.doOnError(error -> log.info("caught error"))
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void doOnErrorIfArithmeticException_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.doOnError(
ArithmeticException.class,
error -> log.info("caught error")
)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void doOnErrorIfPredicatePasses_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.doOnError(
error -> error instanceof ArithmeticException,
error -> log.info("caught error")
)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void OnErrorMap_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorMap(error -> new RuntimeException("SomeMathException"))
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void OnErrorMapIfArithmeticException_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorMap(
ArithmeticException.class,
error -> new RuntimeException("SomeMathException")
)
.subscribe(num -> log.info("Number: {}", num ));
}
@Test
public void OnErrorMapIfPredicatePasses_Mono() {
Mono.just(2)
.map(i -> i/0) // will produce ArithmeticException
.onErrorMap(
error -> error instanceof ArithmeticException,
error -> new RuntimeException("SomeMathException")
)
.subscribe(num -> log.info("Number: {}", num ));
}
Upvotes: 85