Reputation: 1568
I made a simple spring boot application. I have a REST endpoint that returns a hot stream of the current time.
@RestController
public class NowResource {
@GetMapping(value = "/now", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> now() {
return Flux.interval(Duration.ofSeconds(1))
.flatMap(t -> Flux.just(Instant.now().toString()));
}
}
When I call http://localhost:8080/now
I get a stream of data that looks like:
data:2018-04-03T13:20:38.313222100Z
data:2018-04-03T13:20:39.311493500Z
data:2018-04-03T13:20:40.310878800Z
...
When I disconnect from the stream (close the browser tab) an IOException
is thrown, caught and the stacktrace printed.
java.io.IOException: An established connection was aborted by the software in your host machine
...
I have tried catching it but it is already caught and does not make it back to my method.
I tried adding doOnTerminate()
, doOnError()
etc. to the Flux but does not seem to have any effect, I'm guessing the actual event is of a different type.
Can I somehow get access to this exception to handle it differently than just printing it? (I would like to avoid have the 200+ lines of output in the log and just print "DONE" instead.)
EDIT: My solution based on the answer from Tomas Pinos
I ended up taking that approach, the difference being that I moved it to a new class and this way it handles all exceptions of this type from all controllers.
@Slf4j
@ControllerAdvice
class IOExceptionHandler implements WebExceptionHandler {
@ExceptionHandler(IOException.class)
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
return Mono.just(ex.getMessage())
.doOnNext(
msg -> log.warn("IOException occurred: {}.", msg)
)
.then();
}
}
Upvotes: 5
Views: 1139
Reputation: 2862
The exception is related to HTTP connection handling between the browser ant the controller (simply put).
It can be handled in controller's @ExceptionHandler
method (or in a @ControllerAdvice
class, if you want to apply the same exception handling across more controllers).
For example:
@RestController
public class NowResource {
...
@ExceptionHandler(IOException.class)
public void handleException(IOException e) {
log.warn("IOException occurred: {}", e.getMessage());
}
}
Upvotes: 4