Home > front end >  Correctly serialize Zalando Problem thrown from Spring filter
Correctly serialize Zalando Problem thrown from Spring filter

Time:06-10

I'm using Zalando's Problem library and am running in the following problem (pun intended):

Everything works fine for problems thrown from normal controllers. In this case I have a custom Spring filter. If I throw a problem from the filter, the response is 500 error (shown using the standard spring error page), and not a 400 error as indicated in the problem. With other words, the exception is thrown like a normal exception, instead of being correctly serialised as a JSON response.

How can I make sure problems thrown from filter's are also correctly handled/serialised?

My code:


@Component
class UserVerifiedFilter : OncePerRequestFilter() {

    @Throws(ServletException::class, IOException::class)
    override fun doFilterInternal(
        request: HttpServletRequest,
        response: HttpServletResponse,
        filterChain: FilterChain
    ) {

       // ...
        throw Problem.builder()
            .withType(URI.create("https://example.org/email-unverified"))
            .withTitle("Email unverified")
            .withStatus(Status.BAD_REQUEST)
            .withDetail("Email needs to verified to use this endpoint")
            .build()


    }
}

@RestControllerAdvice
class ControllerExceptionHandler : ProblemHandling, SecurityAdviceTrait

CodePudding user response:

Managed to solve this by adding another filter, as the first one in the chain.

This filter catches any exception and manually propagates it to the configured exception handlers.

@Component
class FilterExceptionHandler : OncePerRequestFilter() {
    @Autowired
    private lateinit var resolver: HandlerExceptionResolver

    private val logger = LoggerFactory.getLogger(javaClass)

    @Throws(ServletException::class, IOException::class)
    override fun doFilterInternal(
        request: HttpServletRequest,
        response: HttpServletResponse,
        filterChain: FilterChain
    ) {
        try {
            filterChain.doFilter(request, response)
        } catch (exception: Exception) {
            logger.error("Spring Security filter chain exception : {}", exception)
            resolver.resolveException(request, response, null, exception)
        }
    }
}
  • Related