package org.nextprot.api.web;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.nextprot.api.commons.exception.*;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.HttpMediaTypeException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.util.HashSet;
import java.util.Set;
/**
* Advice class to deal with exception. No stack trace should be returned to the
* users, always wraps an unexpected exception.
*
* @author dteixeira
*/
@ControllerAdvice
public class NextprotExceptionHandler {
private static final Log LOGGER = LogFactory.getLog(NextprotExceptionHandler.class);
private static final String ENTRIES_NOT_FOUND = "entriesNotFound";
@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(NotAuthorizedException.class)
@ResponseBody
public RestErrorResponse handle(NotAuthorizedException ex) {
LOGGER.info("Not authorized" + ex.getLocalizedMessage());
return getResponseError(ex);
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(NextProtException.class)
@ResponseBody
public RestErrorResponse handle(NextProtException ex) {
LOGGER.info("NextProt exception" + ex.getLocalizedMessage());
return getResponseError(ex);
}
@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(ConcurrentRequestsException.class)
@ResponseBody
public RestErrorResponse handle(ConcurrentRequestsException ex) {
LOGGER.error("Too many requests!!!!");
return getResponseError(ex);
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(JsonProcessingException.class)
@ResponseBody
public RestErrorResponse handle(JsonProcessingException ex) {
LOGGER.warn("Json Processing " + ex.getLocalizedMessage());
return getResponseError(ex);
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMediaTypeException.class)
@ResponseBody
public RestErrorResponse handle(HttpMediaTypeException ex) {
LOGGER.warn("Bad request " + ex.getLocalizedMessage());
return getResponseError(ex);
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseBody
public RestErrorResponse handle(ResourceNotFoundException ex) {
LOGGER.warn("Resource not found " + ex.getLocalizedMessage());
return getResponseError(ex);
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(DataAccessException.class)
@ResponseBody
public RestErrorResponse handle(DataAccessException ex) {
LOGGER.warn("Data access exception " + ex.getLocalizedMessage());
return getResponseError(ex);
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
@ResponseBody
public RestErrorResponse handle(Exception ex) {
String code = Integer.toHexString(ex.getLocalizedMessage().hashCode() + ex.getClass().getCanonicalName().hashCode()).toUpperCase();
LOGGER.error("unexpected error occurred:" + code + "\t" + ex.getLocalizedMessage());
ex.printStackTrace();
return getResponseErrorMsg("Oops something went wrong.... Try again in a few minutes, if the error persists provide the following code to support : " + code);
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(EntryNotFoundException.class)
@ResponseBody
public RestErrorResponse handle(EntryNotFoundException ex) {
LOGGER.warn("Entry not found exception " + ex.getLocalizedMessage());
RestErrorResponse response = getResponseError(ex);
Set<String> set = new HashSet<>();
set.add(ex.getEntry());
response.setProperty(ENTRIES_NOT_FOUND, (HashSet)set);
return response;
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(EntrySetNotFoundException.class)
@ResponseBody
public RestErrorResponse handle(EntrySetNotFoundException ex) {
LOGGER.warn("Entry set not found exception " + ex.getLocalizedMessage());
RestErrorResponse response = getResponseError(ex);
response.setProperty(ENTRIES_NOT_FOUND, (HashSet)ex.getEntrySet());
return response;
}
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(AccessDeniedException.class)
@ResponseBody
public RestErrorResponse handle(AccessDeniedException ex) {
LOGGER.warn("Some error occured " + ex.getLocalizedMessage());
return getResponseError(ex);
}
@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(DataIntegrityViolationException.class)
@ResponseBody
public RestErrorResponse handle(DataIntegrityViolationException ex) {
LOGGER.warn("Data Integration violation occured " + ex.getLocalizedMessage());
ex.printStackTrace();
return getResponseErrorMsg("conflict with another resource (try to use a different name)");
}
private static RestErrorResponse getResponseError(Throwable t) {
t.printStackTrace();
RestErrorResponse errorResponse = getResponseErrorMsg(t.getLocalizedMessage());
errorResponse.setType(t.getClass().getSimpleName());
return errorResponse;
}
private static RestErrorResponse getResponseErrorMsg(String message) {
RestErrorResponse rer = new RestErrorResponse();
rer.setMessage(message);
return rer;
}
}