为什么声纳认为这个表达式总是错误的

Why does sonar think this expression is always false

在我的 Java 项目中,SonarQube 说表达式总是假的。但是我不明白为什么。这是有问题的代码:

    BaseException baseException = null;

    for (SpaceInfo i: spaceInfos) {
        try {
            processSingle(i.getSpaceKey(), i.getContentType());
        } catch (BaseException e) {
            baseException = BaseException.chain(baseException, e);
        }
    }

    // Here sonar say that this condition will always evaluate to false. 
    if (baseException != null) {
        throw baseException;
    }

但是在我看来,如果 processSingle 方法抛出 BaseException,那么 baseException 不应该为 null,因此表达式的计算结果不应为 false。

processSingle方法声明如下:

private void processSingle(String spaceKey, String contentType) throws BaseException

而且肯定有 processSingle 方法会抛出 BaseException 的情况。所以我认为声纳是错误的。或者这里发生了什么我没有看到的事情?

更新:

这就是 BaseException.chain() 的作用:

public static BaseException chain (BaseException a, BaseException b) {
    if (a == null) { return b; }
    a.setNextException(b);
    return a;
}

这是processSingle的代码:

private void processSingle(String spaceKey, String contentType) throws BaseException {
    assert ContentTypes.Page.equals(contentType) || ContentTypes.BlogPost.equals(contentType);

    Content content;
    try {
        content = createEmptyContent(spaceKey, contentType);
    } catch (Exception e) {
        throw new MessageToContentProcessorProcessSingleException(contentType, spaceKey, e);
    }

    BaseException baseException = null;

    try {
        contentCreator.addMetadata(content);

    } catch (BaseException e) {
        baseException = BaseException.chain(baseException, e);
    }

    Pair<List<AttachmentInfo>, FailedToSaveAttachmentException> pair = contentCreator.saveAttachments(messageParser.getContent(), content);
    List<AttachmentInfo> attachments = pair.getLeft();
    baseException = BaseException.chain(baseException, pair.getRight());

    try {
        String html = htmlGenerator.generateHtml(attachments, messageParser.getContent());
        contentCreator.updateBodyOfContent(content, html);
    } catch (BaseException e) {
        baseException = BaseException.chain(baseException, e);
    }

    if (baseException != null) {
        throw new MessageToContentProcessorProcessSingleException(contentType, spaceKey, baseException);
    }
}

为了testing/curiosity,我会尝试:

} catch (BaseException e) {
    baseException = e;
}

这将显示 Sonar 认为 是否可以抛出异常。或者,如果它通过 chain 方法或赋值语句(赋值给 basseException 但在赋值的右侧使用它(仍然为空))变得 confused

我知道这是在改变逻辑,只是为了测试

甚至尝试(但我不相信这会 trick 声纳)

} catch (BaseException e) {
    var tmp = BaseException.chain(baseException, e);
    baseException = tmp;
}

尝试更改 chain() 以帮助 SonarQube:

public static BaseException chain (BaseException a, BaseException b) {
    if (a == null) { 
        return b; 
    } else {
        a.setNextException(b);
        return a;
    }
}

考虑一下,几乎不可能是问题所在 - a 不是 null 几乎是微不足道的

我会尝试看看它是否有效:

BaseException baseException;

for (SpaceInfo i: spaceInfos) {
    try {
        processSingle(i.getSpaceKey(), i.getContentType());
        baseException = null;
    } catch (BaseException e) {
        baseException = BaseException.chain(baseException, e);
    }
}