WebFlux Error Handling: Operators, Controllers, Global Handlers
Fast recall
Quick revision
Core answer
onErrorResume, onErrorReturn, onErrorMap, retryWhen, timeout) handles recoverable errors inside the reactive chain; controller-level @ExceptionHandler catches signals for one controller; global @RestControllerAdvice maps domain exceptions to HTTP responses consistently; and `WebExceptionHandler` is the last-line catch for filter, routing, and security errors. Status mapping uses ResponseStatusException or RFC 7807 ProblemDetail. Critical gotchas: errors in Reactor are signals — try/catch doesn't catch them; onErrorContinue silently swallows bugs; request context survives only through Reactor Context or the Micrometer Context Propagation bridge.Practical reactive error handling, layered approach, HTTP mapping, observability, and Reactor Context for MDC
Mixing blocking try/catch with reactive chains; using onErrorContinue blindly; losing request context across threads
Discuss ProblemDetail RFC 7807, Reactor Context for MDC, retry with jitter and idempotency, exception hierarchy design, and per-endpoint error budgets
Interview-ready guide
Interview answer
WebFlux error handling layers from inside-out: operator-level, controller-level, global advice, framework-level.
The four layers
Operator-level:
onErrorResume,onErrorReturn,onErrorMapfor recovery and translationretryWhenwith backoff for transient failurestimeouton every outbound call
Controller-level:
@ExceptionHandleron a specific controller
Global:
@RestControllerAdvicemapping domain exceptions to HTTP- One place for consistent
ProblemDetailresponses
Framework-level:
WebExceptionHandlerfor filter, routing, security errors- Last line of defense
Rules of thumb
- Recoverable / expected → operator-level
- Domain → HTTP mapping → global advice
- Truly unexpected → framework-level returns generic 5xx
Critical things to mention
- Errors in Reactor are signals, not thrown exceptions;
try/catchdoesn't catch them .block()in reactive code defeats non-blocking and risks deadlock- Never swallow errors silently — at minimum log or count them
onErrorContinueis inconsistent across operators; prefer per-itemflatMapplusonErrorResume- Reactor
Contextplus Micrometer Context Propagation keeps MDC and trace IDs across thread hops - Every outbound call needs an explicit timeout — defaults are too long or absent
- Don't retry 4xx, don't retry non-idempotent writes without an idempotency key
HTTP error contract
- RFC 7807
ProblemDetailis the modern standard, built into Spring 6 - Content-Type
application/problem+json - Fields:
type,title,status,detail,instance, plus custom properties - Always include a trace ID so users can report and on-call can search
Strategic answer
- Operator-level for recovery; global advice for HTTP mapping; framework-level for last-line
- Errors are first-class citizens, not afterthoughts
- Consistent exception hierarchy +
ProblemDetail= clean error contract - Log with context, alert on rates, never expose internals to users
WebFlux Error Handling: Operators, Controllers, Global Handlers
Direct Answer
WebFlux error handling layers from inside-out: operator-level (onErrorResume, onErrorReturn, onErrorMap, retryWhen, timeout) handles recoverable errors inside the reactive chain; controller-level @ExceptionHandler catches signals for one controller; global @RestControllerAdvice maps domain exceptions to HTTP responses consistently; and WebExceptionHandler is the last-line catch for filter, routing, and security errors. Status mapping uses ResponseStatusException or RFC 7807 ProblemDetail. Critical gotchas: errors in Reactor are signals — try/catch doesn't catch them; onErrorContinue silently swallows bugs; request context survives only through Reactor Context or the Micrometer Context Propagation bridge.
Common Mistakes & Pitfalls
Mixing blocking try/catch with reactive chains; using onErrorContinue blindly; losing request context across threads
Check your understanding
Answer these without looking back at the article.
- What is RFC 7807 Problem Details and how do you use it in Spring?
- How do you propagate MDC and request context to error logs in reactive code?
- When should you retry a failed upstream call vs fail fast?
- Compare ResponseStatusException vs custom exception plus @ControllerAdvice
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.