001package co.codewizards.cloudstore.rest.server.jersey;
002
003import javax.ws.rs.WebApplicationException;
004import javax.ws.rs.core.Context;
005import javax.ws.rs.core.MediaType;
006import javax.ws.rs.core.Response;
007import javax.ws.rs.ext.ExceptionMapper;
008import javax.ws.rs.ext.Provider;
009
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013import co.codewizards.cloudstore.core.concurrent.DeferredCompletionException;
014import co.codewizards.cloudstore.core.dto.Error;
015import co.codewizards.cloudstore.core.dto.ErrorStackTraceElement;
016import co.codewizards.cloudstore.rest.server.CloudStoreREST;
017
018/**
019 * @author unascribed
020 * @author Chairat Kongarayawetchakun - ckongarayawetchakun at nightlabs dot de
021 */
022@Provider
023public class DefaultExceptionMapper implements ExceptionMapper<Throwable>
024{
025        private static final Logger logger = LoggerFactory.getLogger(DefaultExceptionMapper.class);
026
027        public DefaultExceptionMapper(@Context CloudStoreREST cloudStoreREST) {
028                logger.debug("<init>: Instance created. cloudStoreREST={}", cloudStoreREST);
029
030                if (cloudStoreREST == null)
031                        throw new IllegalArgumentException("cloudStoreREST == null");
032
033        }
034
035        @Override
036        public Response toResponse(Throwable throwable)
037        {
038                // We need to log the exception here, because it otherwise doesn't occur in any log
039                // in a vanilla tomcat 7.0.25. Marco :-)
040                if (throwable instanceof DeferredCompletionException) // normal part of protocol => only debug
041                        logger.debug(String.valueOf(throwable), throwable);
042                else
043                        logger.error(String.valueOf(throwable),throwable);
044
045                if (throwable instanceof WebApplicationException) {
046                        return ((WebApplicationException)throwable).getResponse();
047                }
048
049                Error error = new Error(throwable);
050                Error e = error;
051
052                Throwable t = throwable;
053                while (t != null) {
054                        for (StackTraceElement stackTraceElement : t.getStackTrace()) {
055                                e.getStackTraceElements().add(new ErrorStackTraceElement(stackTraceElement));
056                        }
057
058                        t = t.getCause();
059                        if (t != null) {
060                                Error oldE = e;
061                                e = new Error(t);
062                                oldE.setCause(e);
063                        }
064                }
065                return Response
066                                .status(Response.Status.INTERNAL_SERVER_ERROR)
067                                .type(MediaType.APPLICATION_XML)
068                                .entity(error)
069                                .build();
070        }
071}