3

我用 Java 管理一个开源项目,在我的代码中有大约 20 个位置,我使用以下模式记录异常(slf4j 版本 1.7.30)

private static final Logger logger = LoggerFactory.getLogger();

... 

try {
  interfaces = NetworkInterface.getNetworkInterfaces(); 
} catch (SocketException ex) {
  logger.error("Socket exception when retrieving interfaces: {}", ex);
}

或类似的

try {
  // stuff
} catch (IOException ioe) {
  logger.error("Server error: {}", ioe);
}

从今天开始,SonarCloud自动代码质量审查已开始使用规则java:S2275(Printf 样式的格式字符串不应导致运行时出现意外行为)和特定消息“没有足够的参数”来标记这些。

编辑:值得注意的是,当 anException是最后一个论点时,这似乎一直发生。以下模式不会标记

try {
  // Server connection code
} catch (IOException e) {
  logger.error("Server Connection error: {}", e.getMessage());
}

对另一个 StackOverflow 问题的回顾表明,异常的额外参数可能是可选的,并且会导致不同的行为,所以我不清楚这将如何应用在这里以及为什么它会突然改变。

我可以/应该做些什么来更好地将这些异常转换为日志消息(例如,getMessage()在所有异常上使用而不是依赖自动toString()解析),或者这是误报?

(Sonar 的我的 20 个问题列表链接在这里。)

4

1 回答 1

9

这纯属猜想,但每个问题都指向一个日志行,可以概括为:

LOG.something(format, custom_arguments, exception)

{}出现格式的地方count(custom_arguments) + 1(为例外保留的 1)。

正如您所看到的链接答案,异常会被 slf4j 特殊处理,因此由于某种原因,SonarCloud 可能正在做同样的事情。不幸的是,没有文档。

“修复”将删除{}用于异常的最终结果,例如

LOG.error("boom: {}", e);
LOG.error("boom2 {}: {}", something, e);

变成

// exceptions handled in a special way
LOG.error("boom", e);
LOG.error("boom2 {}", something, e);
于 2020-03-12T05:50:16.160 回答