Search code examples
javaspring-bootspring-webfluxreactive-programming

Throw exception by condition. Spring web flux


I have the following reactive code. And I want to throw my custom exception, if return value is null

ReactiveSecurityContextHolder.getContext()
                .map(SecurityContext::getAuthentication)
                .map(authentication ->(UserAuthenticationToken) authentication)
                .map(UserAuthenticationToken::getUserPrincipalName)
                //Here I want to throw exception, if 
                 //UserAuthenticationToken::getUserPrincipalName will return null

something like :

 .map(UserAuthenticationToken::getUserPrincipalName)
               .switchIfEmpty(Mono.error(new MissingPrincipalException("Missing email field in the JWT token")));

or :

.map(UserAuthenticationToken::getUserPrincipalName)
               .filter(principal -> !Objects.isNull(principal))
               .switchIfEmpty(Mono.error(new MissingPrincipalException("Missing email field in the JWT token")))

does not work.


Solution

  • The reactive streams specification disallows null values in a sequence, therefore you can't use map(UserAuthenticationToken::getUserPrincipalName).

    One way to handle such case is to use flatMap

    ReactiveSecurityContextHolder.getContext()
         .map(ctx -> (UserAuthenticationToken) ctx.getAuthentication())
         .flatMap(token -> {
            if (token.getUserPrincipalName() == null) {
                 return Mono.error(new MissingPrincipalException("Missing email field in the JWT token"));
            }
            
            return Mono.just(token.getUserPrincipalName());
         })
    

    You can also use handle operator to remove any nulls. Reactor Reference Guide has a good example for Using handle for a "map and eliminate nulls" scenario