长说明:我正在使用Spring Boot创建一个简单的rest服务。我喜欢默认情况下没有堆栈跟踪,并且使用基本的异常细节(状态、错误、消息)创建JSON响应来处理自定义异常。
问题是它也不创建任何日志条目,因此我必须手动执行此操作:
自定义异常
@ResponseStatus(value = HttpStatus.CONFLICT)
public class DuplicateFoundException extends RuntimeException {
public DuplicateFoundException(String message) {
super(message);
}
}
在 @RestController 中的服务方法中抛出异常
if (!voteDao.findByItemAndUser(item, voteDto.getUserId()).isEmpty()) {
log.warn("... already voted ..."); //TODO: don't do this for every throw
throw new DuplicateFoundException("... already voted ...");
}
有更多的异常会导致在每个抛出之前放置日志语句,我认为这是一种不好的方法。我尝试从服务方法中删除所有日志记录,并创建@ControllerAdvice
,在其中记录所有自定义异常并重新抛出它们,以便仍然获得像以前一样漂亮的JSON:
@ControllerAdvice
public class RestExceptionHandler {
private static final Logger log = Logger.getLogger(RestExceptionHandler.class);
@ExceptionHandler
public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
log.warn(e.getMessage());
} else {
log.error("...");
}
throw e;
}
}
现在问题是我不仅看到了日志条目,还看到了自定义异常的堆栈跟踪,并且找不到如何防止这种情况的方法。我认为这个问题是由于再次抛出异常引起的。可能的解决方法是创建一个自定义异常类,然后返回该类,但我不喜欢这个想法,因为异常编组似乎很好用。有什么提示吗?
log.warn
行,但同时也记录了整个异常?我可能错了,但我之前见过不会抛出异常的@ExceptionHandler
,它们只是返回一个ResponseEntity
(带有状态500等)。 - rogerdpack