Reputation: 1446
My code is as below
public Mono<Ship> getShip() {
//...
}
public Mono<Car> getCar() {
//...
}
public Mono<ShipAndCar> getCombinedMono() {
Mono<Ship> shipMono = getShip();
Mono<Car> carMono = getCar();
return Mono.zip(shipMono, carMono
(ship, car) -> return new ShipAndCar(ship, car);
}
As both getShip
and getCar
can return error or empty Mono. I'd like to return something like Mono.error(new Exception("Custom message"))
where the message depends on which Mono is empty. How do I do that?
If I add a switchIfEmpty
after the Mono.zip, I wouldn't know which component Mono is empty...
Upvotes: 0
Views: 2254
Reputation: 1406
You can supply default arguments in the case of an empty Producer:
package com.example.demo;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
public class JavaTest {
@Test
public void nullCarProducesSpecificException() {
Mono<Ship> shipMono = Mono.empty();
Mono<Car> carMono = Mono.empty();
var map = Mono.zip(
shipMono.defaultIfEmpty(new Ship("US Default")),
carMono.switchIfEmpty(Mono.error(new RuntimeException("Car was missing!!"))))
.map(tuple -> new ShipAndCar(tuple.getT1(), tuple.getT2()));
StepVerifier.create(map)
.verifyErrorMatches(error ->
error instanceof RuntimeException &&
"Car was missing!!".equals(error.getMessage())
);
}
}
Upvotes: 1
Reputation: 774
If you zip them in your code you can extend each input mono with the switchIfEmpty operator like this
var carAndShip = Mono.zip(
Optional.ofNullable(shipMono)
.orElseThrow(() -> new RuntimeException("ship is null"))
.switchIfEmpty(Mono.error(new RuntimeException("ship is empty"))),
Optional.ofNullable(carMono)
.orElseThrow(() -> new RuntimeException("car is null"))
.switchIfEmpty(Mono.error(new RuntimeException("car is empty"))),
ShipAndCar::new
);
Upvotes: 0