Spring 5 webflux exception handling

  springboot

Order

This article mainly studies the exception handling of spring 5 webflux.

maven

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

ExceptionHandler

Since webflux also supports most of the annotations of traditional spring mvc, the original ExceptionHandler is also supported.

@RestControllerAdvice
public class ExceptionHandlers {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionHandlers.class);

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String serverExceptionHandler(Exception ex) {
        LOGGER.error(ex.getMessage(),ex);
        return ex.getMessage();
    }
}

You can see the log at startup.

2018-02-12 19:26:03.249  INFO 7053 --- [           main] o.s.w.r.r.m.a.ControllerMethodResolver   : Looking for @ControllerAdvice: org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext@65d09a04: startup date [Mon Feb 12 19:25:59 CST 2018]; root of context hierarchy
2018-02-12 19:26:03.281  INFO 7053 --- [           main] o.s.w.r.r.m.a.ControllerMethodResolver   : Detected @ExceptionHandler methods in exceptionHandlers

spring-webflux-5.0.2.RELEASE-sources.jar! /org/springframework/web/reactive/result/method/annotation/ControllerMethodResolver.java

/**
 * Package-private class to assist {@link RequestMappingHandlerAdapter} with
 * resolving, initializing, and caching annotated methods declared in
 * {@code @Controller} and {@code @ControllerAdvice} components:
 * <ul>
 * <li>{@code @InitBinder}
 * <li>{@code @ModelAttribute}
 * <li>{@code @RequestMapping}
 * <li>{@code @ExceptionHandler}
 * </ul>
 *
 * @author Rossen Stoyanchev
 * @since 5.0
 */
class ControllerMethodResolver {

    private static Log logger = LogFactory.getLog(ControllerMethodResolver.class);


    private final List<SyncHandlerMethodArgumentResolver> initBinderResolvers;

    private final List<HandlerMethodArgumentResolver> modelAttributeResolvers;

    private final List<HandlerMethodArgumentResolver> requestMappingResolvers;

    private final List<HandlerMethodArgumentResolver> exceptionHandlerResolvers;

    private final ReactiveAdapterRegistry reactiveAdapterRegistry;
    //......
}

You can see the comments that support InitBinder, ModelAttribute, RequestMapping, ExceptionHandler.

Example

    @GetMapping(value = "/error",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Mono<String> exceptionReturn(){
//        throw new RuntimeException("hello");
        return Mono.error(new RuntimeException("test error"));
    }

Different from traditional mvc, except for the direct throw exception, Mono or Flux can directly error an exception, which can be received and processed in exceptionHandlers.

Summary

Webflux supports mvc annotations, which is a very convenient function. Compared with RouteFunction, automatic scanning and registration is more convenient. ExceptionHandler can be used for exception handling.