001package co.codewizards.cloudstore.ls.rest.server;
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;
016
017/**
018 * @author Marco หงุ่ยตระกูล-Schulze - marco at codewizards dot co
019 * @author Chairat Kongarayawetchakun - ckongarayawetchakun at nightlabs dot de
020 */
021@Provider
022public class DefaultExceptionMapper implements ExceptionMapper<Throwable>
023{
024        private static final Logger logger = LoggerFactory.getLogger(DefaultExceptionMapper.class);
025
026        public DefaultExceptionMapper(@Context final LocalServerRest localServerRest) {
027                logger.debug("<init>: Instance created. localServerRest={}", localServerRest);
028
029                if (localServerRest == null)
030                        throw new IllegalArgumentException("localServerRest == null");
031
032        }
033
034        @Override
035        public Response toResponse(final Throwable throwable)
036        {
037                // We need to log the exception here, because it otherwise doesn't occur in any log
038                // in a vanilla tomcat 7.0.25. Marco :-)
039                if (throwable instanceof DeferredCompletionException) // normal part of protocol => only debug
040                        logger.debug(String.valueOf(throwable), throwable);
041                else
042                        logger.error(String.valueOf(throwable),throwable);
043
044                if (throwable instanceof WebApplicationException) {
045                        return ((WebApplicationException)throwable).getResponse();
046                }
047
048                final Error error = new Error(throwable);
049                Error e = error;
050
051                Throwable t = throwable;
052                while (t != null) {
053                        for (final StackTraceElement stackTraceElement : t.getStackTrace()) {
054                                e.getStackTraceElements().add(new ErrorStackTraceElement(stackTraceElement));
055                        }
056
057                        t = t.getCause();
058                        if (t != null) {
059                                final Error oldE = e;
060                                e = new Error(t);
061                                oldE.setCause(e);
062                        }
063                }
064                return Response
065                                .status(Response.Status.INTERNAL_SERVER_ERROR)
066                                .type(MediaType.APPLICATION_XML)
067                                .entity(error)
068                                .build();
069        }
070}