Sia
Sia

Reputation: 159

doOnNext() won't get called Spring Webflux

I'm a newbie in reactive programming and also Spring Webflux I have a method to get some key from Redis and if this key is null or is not equals to the specified string i want to throw an exception but the nested donOnNext method won't get called and customerRepository.save(customer) get triggered while the exception must be thrown and break the chain. Can someone explain to me how the reactor API behaves in my case?

this is my method:

@Override
public Mono<RegistrationVerificationResDTO> verifyCustomerAndGenerateToken(Mono<VerifyOtpReqDTO> verifyOtpReqDTO) {
    return verifyOtpReqDTO
            .doOnNext(verifyDTO -> reactiveRedisOperations
                    .opsForValue()
                    .get(RedisDictionary.OTP_KEY + verifyDTO.getPhoneNumber())
                    .filter(otp -> otp.equalsIgnoreCase(verifyDTO.getOtp()))
                    .switchIfEmpty(Mono.error(ForbiddenException::new)))
            .map(verifyDTO -> customerRepository.findById(verifyDTO.getId())
                    .orElseThrow(() -> new NotFoundException("Customer not found")))
            .doOnNext(customer -> {
                customer.setVerified(true);
                customerRepository.save(customer);
            })
            .map(customer -> new RegistrationVerificationResDTO().setAccessToken("accessToken")
                    .setRefreshToken("refreshToken")
                    .setCustomer(customer));
}

UPDATE: I realized if we create another publisher inside the doOnNext method because the spring just subscribes to the most outer publisher the inner one won't get triggered I have updated my code but it still doesn't work.

Upvotes: 6

Views: 6643

Answers (1)

Simon Basl&#233;
Simon Basl&#233;

Reputation: 28301

I'm guessing you're saying this "doesn't work" because you can't observe the saved customer in DB, even after the (correct) changes you've made to the second (innermost) doOnNext?

The third doOnNext is problematic: customerRepository.save(customer) is a NO-OP assuming customerRepository is a reactive repository, because the (lazy) Mono is neither attached to the main sequence nor subscribed to.

Simply replace that doOnNext with flatMap (and keep your changes to the innermost doOnNext with switchIfEmpty as well) to make it part of the reactive chain that Spring will subscribe to.

Upvotes: 4

Related Questions