package com.syzton.sunread.controller;
import java.sql.SQLException;
import java.util.List;
import java.util.Locale;
import com.syzton.sunread.exception.common.UpLoadException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
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 com.syzton.sunread.common.dto.ValidationErrorDTO;
import com.syzton.sunread.exception.common.DatabaseException;
import com.syzton.sunread.exception.common.DuplicateException;
import com.syzton.sunread.exception.common.NotFoundException;
import com.syzton.sunread.exception.store.InSufficientCoinsException;
/**
* @author Chenty
*/
@ControllerAdvice
public class ControllerErrorHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(ControllerErrorHandler.class);
private MessageSource messageSource;
@Autowired
public ControllerErrorHandler(MessageSource messageSource) {
this.messageSource = messageSource;
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ValidationErrorDTO processValidationError(MethodArgumentNotValidException ex) {
BindingResult result = ex.getBindingResult();
List<FieldError> fieldErrors = result.getFieldErrors();
return processFieldErrors(fieldErrors);
}
private ValidationErrorDTO processFieldErrors(List<FieldError> fieldErrors) {
ValidationErrorDTO dto = new ValidationErrorDTO();
for (FieldError fieldError: fieldErrors) {
String localizedErrorMessage = resolveLocalizedErrorMessage(fieldError);
dto.addFieldError(fieldError.getField(), localizedErrorMessage);
}
return dto;
}
private String resolveLocalizedErrorMessage(FieldError fieldError) {
Locale currentLocale = LocaleContextHolder.getLocale();
String localizedErrorMessage = messageSource.getMessage(fieldError, currentLocale);
//If the message was not found, return the most accurate field error code instead.
//You can remove this check if you prefer to get the default error message.
if (localizedErrorMessage.equals(fieldError.getDefaultMessage())) {
String[] fieldErrorCodes = fieldError.getCodes();
localizedErrorMessage = fieldErrorCodes[0];
}
return localizedErrorMessage;
}
@ExceptionHandler(NotFoundException.class)
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public String handleNotFoundException(Exception ex) {
LOGGER.debug(ex.getMessage());
return ex.getMessage();
}
@ExceptionHandler(DuplicateException.class)
@ResponseStatus(value = HttpStatus.CONFLICT)
@ResponseBody
public String handleDuplicateException(Exception ex) {
LOGGER.debug(ex.getMessage());
return ex.getMessage();
}
@ExceptionHandler(DatabaseException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public String handleDatabaseException(Exception ex) {
LOGGER.debug(ex.getMessage());
return ex.getMessage();
}
@ExceptionHandler(UpLoadException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public String handleUploadException(Exception ex) {
LOGGER.debug(ex.getMessage());
return ex.getMessage();
}
@ExceptionHandler(SQLException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public String handleSQLException(Exception ex) {
LOGGER.debug(ex.getMessage());
return ex.getMessage();
}
@ExceptionHandler(NumberFormatException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public String handleNumberFormatException(Exception ex) {
LOGGER.debug(ex.getMessage());
return ex.getMessage();
}
@ExceptionHandler(InSufficientCoinsException.class)
@ResponseStatus(value = HttpStatus.INSUFFICIENT_STORAGE)
@ResponseBody
public String handleInSufficientCoinsException(Exception ex) {
LOGGER.debug(ex.getMessage());
return ex.getMessage();
}
}