package ameba.message.jackson.internal; import ameba.core.Application; import ameba.message.error.ErrorMessage; import ameba.message.error.ExceptionMapperUtils; import ameba.util.IOUtils; import ameba.util.Result; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.hash.Hashing; import org.glassfish.jersey.spi.ExceptionMappers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; import javax.persistence.PersistenceException; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; /** * <p>JsonProcessingExceptionMapper class.</p> * * @author icode */ @Singleton public class JsonProcessingExceptionMapper implements ExceptionMapper<JsonProcessingException> { private static final Logger logger = LoggerFactory.getLogger(JsonProcessingExceptionMapper.class); @Context private Provider<ExceptionMappers> exceptionMappers; @Inject private Application.Mode mode; /** * {@inheritDoc} */ @Override public Response toResponse(JsonProcessingException exception) { Throwable throwable = exception; while (throwable != null) { if (throwable instanceof PersistenceException) { return exceptionMappers.get().findMapping(throwable).toResponse(throwable); } throwable = throwable.getCause(); } logger.debug("Json Processing error", exception); String message = exception.getOriginalMessage(); String desc = null; String source = null; if (mode.isDev()) { desc = IOUtils.getStackTrace(exception); JsonLocation location = exception.getLocation(); if (location != null) { source = "line: " + location.getLineNr() + ", column: " + location.getColumnNr(); } else { source = exception.getStackTrace()[0].toString(); } } ErrorMessage errorMessage = ErrorMessage.fromStatus(Response.Status.BAD_REQUEST.getStatusCode()); errorMessage.setThrowable(exception); errorMessage.setCode(Hashing.murmur3_32().hashUnencodedChars(exception.getClass().getName()).toString()); errorMessage.addError(new Result.Error( errorMessage.getCode(), message != null ? message : exception.getMessage(), desc, source )); return Response.status(errorMessage.getStatus()) .entity(errorMessage) .type(ExceptionMapperUtils.getResponseType()) .build(); } }