hydradon
hydradon

Reputation: 1446

Spring Webflux: Handle error when one Mono is empty in a Mono.zip

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

Answers (2)

Adam Bickford
Adam Bickford

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

Alex K.
Alex K.

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

Related Questions