在 Spring Boot 应用程序中防止自定义异常的堆栈跟踪日志记录

新手上路,请多包涵

Spring Boot (MVC) 中是否有一种方法可以记录自定义异常并在日志文件中不显示其堆栈跟踪的情况下抛出它?但是对于任何其他异常,仍然可以看到堆栈跟踪。

长解释:

我正在使用 spring boot 创建一个简单的休息服务。我喜欢自定义异常,默认情况下日志中没有堆栈跟踪,并且使用基本异常详细信息(状态、错误、消息)创建 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;
    }
}

现在的问题是,我不仅看到了日志条目,还看到了自定义异常的堆栈跟踪,但找不到如何防止这种情况发生的方法。我认为问题是再次抛出引起的。一个可能的解决方案是为异常创建一个自定义类,我将返回它,但我不喜欢这个想法,因为异常编组似乎工作正常。

有什么提示吗?

原文由 rhorvath 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 926
2 个回答

解决方案是 将异常处理留给 spring boot ,以便不记录自定义异常,默认情况下记录任何其他异常。我删除了 @ControllerAdvice 以及其余控制器中的日志记录语句, 并将日志记录语句添加到自定义异常构造函数 中。

 public DuplicateFoundException(String message) {
    super(message);
    LOGGER.warn(message);
}

我不确定这是否是最好的方法,但现在我只在一个地方进行自定义异常日志记录,而不必为每个异常重复日志语句或查看其堆栈跟踪或日志中的任何其他错误消息。

原文由 rhorvath 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题