【问题标题】:Why does squid:S1166 not accept exception messages only when logging caught exceptions?为什么 squid:S1166 只有在记录捕获的异常时才接受异常消息?
【发布时间】:2015-10-09 07:16:43
【问题描述】:

引用规则描述(SonarQube 4.5.5):

// Noncompliant - exception is lost (only message is preserved)   
try { /* ... */ } 
catch (Exception e) { LOGGER.info(e.getMessage()); }

通过向记录器提供异常类,将堆栈跟踪写入日志。

我们代码库中的问题是: 通过遵循Tell, don't ask 原则,我们将检查的异常用作我们认为的正常执行路径的一部分,并且我们不希望它们导致不合理的大日志消息。

几个例子:服务器响应错误代码,数据库语句执行因乐观锁定失败(并发用户)...

我的建议:将此案一分为二。

// Noncompliant - exception is lost (only message is preserved)
try { /* ... */ } 
catch (Exception e) { LOGGER.info(e.getMessage()); } 

// Compliant - exception is lost (only message is preserved) but there is business logic handling the situation      

try { 
/* ... */  
} catch (Exception e) {   
   LOGGER.info(e.getMessage());  
   */ exception handling  */  
}

规则 squid:S00108(代码块不能为空)不会发现问题,因为有一个日志语句。

这不合理吗?我错过了什么重要的事情吗?

注意:我已经重写了问题以澄清我的用例

【问题讨论】:

    标签: java sonarqube sonarqube-4.5


    【解决方案1】:

    我理解维护堆栈跟踪和所有这些的论点,但我认为它会使您的日志因

    【讨论】:

      【解决方案2】:

      如果它导致了数百个您认为是 FP 的情况,那么您应该考虑关闭该规则,或 excluding it from your project files

      但要回答你的问题:

      异常记录的目的是为调查人员留下足够的信息以找出问题的原因。

      如果您的消息很详细,例如

      y 方法中的 x 坏了,因为 frabjous 不够一天

      那么也许他们实现了这个目的。但是像这样的消息呢

      出了点问题

      ?

      此外,确切地知道每条异常消息的含义,但总有一天你可能会转向更大更好的事情。下一个支持该系统的人会有同样的知识深度吗? 可能会感谢堆栈跟踪和行号告诉他从哪里开始寻找......

      但最后,我不得不问:为什么你会获取并记录如此多的异常以致于淹没记录器?

      【讨论】:

      • 我发现规则有效(在大多数情况下)并希望保留它,否则我不会费心写一篇关于它的帖子。有问题的应用程序相当大(大约 200 000 行代码)并记录了很多关于用户会话的有用信息,但是当用户执行一些会导致检查异常的事情(由应用程序优雅地处理)时,记录器是不合理的淹没。当然,我可以在较低的日志级别记录所有内容以避免违反规则,但这会迫使我为了我不同意的规则而进行所有这些重写。
      • 我们是否在谈论可能规则应该忽略的特定异常类型,@Alix?
      • 我不认为定义这样的列表会有所帮助,因为自定义异常类很常见,有时来自框架,因此不是标准库。
      • 注意:Hundreds 是一种夸张但相当接近 :-) 异常的一个例子是并发异常
      • 一位同事对此问题的评论:“如果您总是将异常视为真正异常和意外的东西,那么我会同意该规则,但我猜大多数应用程序也将异常作为异常事件流,但并非意外,您可以适当地捕获和处理。对我来说,一个合规的解决方案应该是有一个带有一些逻辑的 catch 块,如何解决这种情况并记录异常消息,而不是带有堆栈跟踪的完整异常. "
      【解决方案3】:

      (添加另一个答案来解决重写的问题:)

      为什么你们要同时处理异常记录它?如果处理好了,就没有理由登录了。

      【讨论】:

      • 我们不仅记录问题,还记录用户流(使用 INFO 日志级别),以便能够查看问题发生之前发生的情况。在这种情况下,我们可能会使用 WARN 日志级别记录发生的任何事情,以标记存在问题但由应用程序处理(错误级别表示无法处理的意外事件)
      【解决方案4】:

      尝试将整个对象传递给方法,而不仅仅是 e.getMessage()LOGGER.info("INFO "e.);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-09
        • 1970-01-01
        • 1970-01-01
        • 2013-02-01
        • 1970-01-01
        • 2016-02-27
        • 1970-01-01
        • 2010-11-01
        相关资源
        最近更新 更多