javajax-rsthorntailexceptionmapper

Why CORSFilter conflicts with ExceptionMapper<Throwable>?


I have this Java thorntail application, where I wanted to catch all uncaught exceptions.

I wanted to respond with 500 instead of the default error page that JAXRS gives, so I just used implementation of ExceptionMapper<Throwable>.

Did the testing using Postman without issues, but once I tried to do the AJAX call in browser, I ended up sending OPTIONS request, which is failing.

CORS part is also implemented on the application side by implementing ContainerResponseFilter.

I have a feeling that MATCHING happens in an early stage of request and only later the CORSFilter has effect on the response.

Few things that I already tried:

// CORSFilter
package com.testapplication.test.rest;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class CORSFilter implements ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        responseContext.getHeaders().add("Access-Control-Max-Age", "-1");
        responseContext.getHeaders().add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    }
}
// UncaughtExceptionMapper
package com.testapplication.test.rest;

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class UncaughtExceptionMapper extends Throwable implements ExceptionMapper<Throwable> {
    @Override
    public Response toResponse(Throwable exception) {
        exception.printStackTrace();
        return Response.status(500).entity("{\"message\": \"a\"}").build();
    }
}

Example repository: https://github.com/trimpirim/cors-filter-conflict-exception-mapper


Solution

  • Try the filter at the bottom of this post. Just using a response filter will not perform correctly in regards to the CORS interaction. You need a request filter also to abort the request for the preflight requests.