package org.jboss.seam.rest.exceptions.integration; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.enterprise.inject.Instance; import javax.enterprise.inject.Specializes; import javax.inject.Inject; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.ext.ExceptionMapper; import org.apache.deltaspike.core.api.exception.control.annotation.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.annotation.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.jboss.solder.logging.Logger; import org.jboss.solder.exception.control.CaughtException; import org.jboss.solder.exception.control.Precedence; //import org.jboss.solder.exception.control.ExceptionToCatch; //import org.jboss.solder.exception.control.Handles; //import org.jboss.solder.exception.control.HandlesExceptions; //import org.jboss.solder.exception.control.Precedence; //import org.jboss.solder.exception.control.TraversalMode; import org.jboss.seam.rest.exceptions.RestRequest; import org.jboss.seam.rest.exceptions.RestResource; import org.jboss.seam.rest.exceptions.SeamExceptionMapper; /** * A JAX-RS ExceptionMapper implementation that maps all exceptions (i.e., Throwable) raised during a JAX-RS request to the Seam * Catch exception handling bus. * <p> * Exceptions are send to Seam Catch by firing an event of type {@link ExceptionToCatch} to the CDI event bus. The event payload * contains the exception and the qualifier @RestRequest. The qualifier allows handlers that deal specifically with REST * requests to be selected. * </p> * * @author <a href="http://community.jboss.org/people/dan.j.allen">Dan Allen</a> * @author <a href="http://community.jboss.org/people/jharting">Jozef Hartinger</a> */ @ApplicationScoped //@HandlesExceptions @ExceptionHandler @Specializes public class CatchExceptionMapper extends SeamExceptionMapper implements ExceptionMapper<Throwable> { @Inject @RestResource private Instance<Response> response; @Inject private Event<ExceptionToCatchEvent> bridgeEvent; private static final Logger log = Logger.getLogger(CatchExceptionMapper.class); @Override public Response toResponse(Throwable exception) { ExceptionToCatchEvent payload = new ExceptionToCatchEvent(exception, RestRequest.RestRequestLiteral.INSTANCE); // The call returns if the exception is handled. The exception is rethrown by catch otherwise. bridgeEvent.fire(payload); return response.get(); } public void handleException( // , during = TraversalMode.DEPTH_FIRST @Handles(ordinal = Precedence.BUILT_IN) @RestRequest CaughtException<Throwable> event, @RestResource ResponseBuilder builder) { Class<? extends Throwable> exceptionType = event.getException().getClass(); log.debugv("Handling {0}", exceptionType); if (getMappings().containsKey(exceptionType)) { produceResponse(event.getException(), builder); event.handled(); } else { event.rethrow(); event.unmute(); // let us handle the causing exception } } }