All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.simter.rest.jaxrs.ThrowableExceptionMapper Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
package tech.simter.rest.jaxrs;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Priority;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.Priorities;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import java.util.Map;

/**
 * The deepest base exception mapper
 *
 * @author RJ 2017-04-29
 */
@Named
@Singleton
@Provider
@Priority(Priorities.USER + 100)
public class ThrowableExceptionMapper implements ExceptionMapper {
  private final static Logger logger = LoggerFactory.getLogger(ThrowableExceptionMapper.class);
  private final Map, Object> mapper;

  public ThrowableExceptionMapper() {
    mapper = null;
  }

  public ThrowableExceptionMapper(Map, Object> mapper) {
    this.mapper = mapper;
  }

  @Override
  public Response toResponse(Throwable e) {
    if (logger.isDebugEnabled()) logger.debug(e.getMessage(), e);

    // ignore jav-rs standard exception
    if (e instanceof WebApplicationException) return ((WebApplicationException) e).getResponse();
    if (e instanceof ProcessingException) throw (ProcessingException) e;

    Response.ResponseBuilder b = getErrorResponseBuilder().type(MediaType.TEXT_PLAIN);
    if (mapper != null && mapper.containsKey(e.getClass())) {   // use mapper
      Object errorMapper = mapper.get(e.getClass());
      if (errorMapper instanceof ErrorMapper) {
        b.status(((ErrorMapper) errorMapper).status);
        b.entity(((ErrorMapper) errorMapper).entity);
      } else {
        b.entity(errorMapper);                             // use exception message as body
      }
    } else {
      String msg = getDeepMessage(e);
      if (msg == null || msg.isEmpty()) b.entity(e.toString()); // use class name as body
      else b.entity(msg);                                       // use custom message as body
    }
    return b.build();
  }

  public Response.ResponseBuilder getErrorResponseBuilder() {
    return Response.serverError();
  }

  /**
   * Recursive to get the exception message.
   *
   * @param e the exception
   * @return the exception message
   */
  private static String getDeepMessage(Throwable e) {
    if (e == null) return null;
    if (e.getCause() == null) return e.getMessage();

    return getDeepMessage(e.getCause());
  }

  /**
   * Define the error mapper.
   */
  public static class ErrorMapper {
    private Response.Status status;
    private Object entity;

    public ErrorMapper(Object entity) {
      this.status = Response.Status.INTERNAL_SERVER_ERROR;
      this.entity = entity;
    }

    public ErrorMapper(Response.Status status, Object entity) {
      this.status = status;
      this.entity = entity;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy