title: WebFlux @ExceptionHandler in a @ControllerAdvice not called for exception thrown in WebFilter
body: <p>In my WebFlux application (annotated controllers) I noticed that if an exception is thrown from a <code>@RestController</code> method, an <code>@ExceptionHandler</code> within a <code>@ControllerAdvice</code> is executed and the exception is correctly handled. However, if the exception happens earlier, e.g. in a <code>WebFilter</code>, the handler is not executed.</p>
  <p>I read the WebFlux docs and found this: <a href="https://docs.spring.io/spring-framework/docs/5.3.21/reference/html/web-reactive.html#webflux-dispatcher-exceptions" rel="nofollow noreferrer">https://docs.spring.io/spring-framework/docs/5.3.21/reference/html/web-reactive.html#webflux-dispatcher-exceptions</a>:</p>
  <pre><code>However, keep in mind that, in WebFlux, you cannot use a @ControllerAdvice to handle exceptions that occur before a handler is chosen.
  </code></pre>
  <p>So I assume the problem is that in when the filter is running, the handler for the request hasn't been chosen yet. I am not sure if this assumption is correct. Also, if this is indeed the issue, the documentation doesn't explain what to do instead.</p>
  <p>What is the reason for the behavior I'm observing and what do I need to do to for the exception handler to be called?</p>
  <p>Here is the code:</p>
  <pre class="lang-kotlin prettyprint-override"><code>package com.test
  
  import org.springframework.boot.autoconfigure.SpringBootApplication
  import org.springframework.boot.runApplication
  import org.springframework.http.MediaType
  import org.springframework.stereotype.Component
  import org.springframework.web.bind.annotation.*
  import org.springframework.web.reactive.config.EnableWebFlux
  import org.springframework.web.server.ServerWebExchange
  import org.springframework.web.server.WebFilter
  import org.springframework.web.server.WebFilterChain
  import reactor.core.publisher.Mono
  
  fun main(vararg args: String) {
      runApplication&lt;TestApplication&gt;(*args)
  }
  
  @EnableWebFlux
  @SpringBootApplication
  class TestApplication
  
  @RequestMapping
  @RestController
  class TestController {
      @GetMapping(
          &quot;/test&quot;,
          produces = [MediaType.APPLICATION_JSON_VALUE],
      )
      fun test(): Map&lt;String, Any?&gt; {
          throw IllegalArgumentException(&quot;exception from controller&quot;)
  //        return mapOf(&quot;all&quot; to &quot;good&quot;)
      }
  }
  
  @Component
  class ThrowingFilter : WebFilter {
      override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono&lt;Void&gt; {
  //        throw IllegalArgumentException(&quot;exception from filter&quot;)
          return chain.filter(exchange)
      }
  }
  
  @RestControllerAdvice
  class TestExceptionHandler {
      @ExceptionHandler
      fun handle(ex: IllegalArgumentException): ErrorInfo {
          return ErrorInfo(ex.message ?: &quot;bar&quot;)
      }
  }
  
  data class ErrorInfo(
      val errorMessage: String,
  )
  </code></pre>