Skip to content

Commit

Permalink
Handle Result exceptions locally
Browse files Browse the repository at this point in the history
  • Loading branch information
magaupp committed Nov 10, 2024
1 parent a44e3fd commit 1d248cf
Showing 1 changed file with 47 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

Expand Down Expand Up @@ -34,6 +38,22 @@
*/
public class SarifParser implements ParserStrategy {

private static final Logger log = LoggerFactory.getLogger(SarifParser.class);

private static class SarifFormatException extends RuntimeException {

private SarifFormatException(String message) {
super(message);
}
}

private static class InformationMissingException extends RuntimeException {

private InformationMissingException(String message) {
super(message);
}
}

private final ObjectMapper objectMapper = new ObjectMapper();

private final StaticCodeAnalysisTool tool;
Expand Down Expand Up @@ -64,20 +84,34 @@ public StaticCodeAnalysisReportDTO parse(String reportContent) {
Map<String, ReportingDescriptor> ruleOfId = rules.stream().collect(Collectors.toMap(ReportingDescriptor::getId, Function.identity(), (first, next) -> first));

List<Result> results = run.getResults().orElse(List.of());
List<StaticCodeAnalysisIssue> issues = results.stream().map(result -> processResult(result, driver, ruleOfId)).toList();
List<StaticCodeAnalysisIssue> issues = results.stream().map(result -> tryProcessResult(result, driver, ruleOfId)).filter(Objects::nonNull).toList();

return new StaticCodeAnalysisReportDTO(tool, issues);
}

private StaticCodeAnalysisIssue processResult(Result result, ToolComponent driver, Map<String, ReportingDescriptor> ruleOfId) {
private StaticCodeAnalysisIssue tryProcessResult(Result result, ToolComponent driver, Map<String, ReportingDescriptor> ruleOfId) {
try {
return processResult(result, driver, ruleOfId);
}
catch (SarifFormatException | NullPointerException e) {
log.error("The result is malformed", e);
return null;
}
catch (InformationMissingException e) {
log.warn("The result does not contain required information", e);
return null;
}
}

private StaticCodeAnalysisIssue processResult(Result result, ToolComponent driver, Map<String, ReportingDescriptor> ruleOfId) throws SarifFormatException {
PhysicalLocation location = result.getLocations().flatMap(locations -> locations.stream().findFirst()).flatMap(Location::getPhysicalLocation)
.orElseThrow(() -> new RuntimeException("Location needed"));
.orElseThrow(() -> new InformationMissingException("Location needed"));

URI uri = URI.create(location.getArtifactLocation().flatMap(ArtifactLocation::getUri).orElseThrow(() -> new RuntimeException("File path needed")));
URI uri = URI.create(location.getArtifactLocation().flatMap(ArtifactLocation::getUri).orElseThrow(() -> new InformationMissingException("File path needed")));
String path = uri.getPath();

Region region = location.getRegion().orElseThrow(() -> new RuntimeException("Region must be present"));
int startLine = region.getStartLine().orElseThrow(() -> new RuntimeException("Text region needed"));
Region region = location.getRegion().orElseThrow(() -> new SarifFormatException("Region must be present"));
int startLine = region.getStartLine().orElseThrow(() -> new InformationMissingException("Text region needed"));
int startColumn = region.getStartColumn().orElse(1);
int endLine = region.getEndLine().orElse(startLine);
int endColumn = region.getEndColumn().orElse(startColumn + 1);
Expand All @@ -99,9 +133,9 @@ private StaticCodeAnalysisIssue processResult(Result result, ToolComponent drive
return new StaticCodeAnalysisIssue(path, startLine, endLine, startColumn, endColumn, ruleId, category, message, level.toString(), null);
}

private static String getRuleId(Result result) {
return result.getRuleId()
.orElseGet(() -> result.getRule().flatMap(ReportingDescriptorReference::getId).orElseThrow(() -> new RuntimeException("Either ruleId or rule.id must be present")));
private static String getRuleId(Result result) throws SarifFormatException {
return result.getRuleId().orElseGet(
() -> result.getRule().flatMap(ReportingDescriptorReference::getId).orElseThrow(() -> new SarifFormatException("Either ruleId or rule.id must be present")));
}

private static Optional<Integer> getRuleIndex(Result result) {
Expand All @@ -111,18 +145,18 @@ private static Optional<Integer> getRuleIndex(Result result) {
}

@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private static String findMessage(Result result, ToolComponent driver, Optional<ReportingDescriptor> rule) {
private static String findMessage(Result result, ToolComponent driver, Optional<ReportingDescriptor> rule) throws SarifFormatException {
return result.getMessage().getText().orElseGet(() -> lookupMessageById(result, driver, rule));
}

@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private static String lookupMessageById(Result result, ToolComponent driver, Optional<ReportingDescriptor> rule) {
String messageId = result.getMessage().getId().orElseThrow(() -> new RuntimeException("Either text or id must be present"));
private static String lookupMessageById(Result result, ToolComponent driver, Optional<ReportingDescriptor> rule) throws SarifFormatException {
String messageId = result.getMessage().getId().orElseThrow(() -> new SarifFormatException("Either text or id must be present"));

var ruleMessageString = rule.flatMap(ReportingDescriptor::getMessageStrings).map(MessageStrings::getAdditionalProperties).map(strings -> strings.get(messageId));
var globalMessageString = driver.getGlobalMessageStrings().map(GlobalMessageStrings::getAdditionalProperties).map(strings -> strings.get(messageId));

var messageString = ruleMessageString.or(() -> globalMessageString).orElseThrow(() -> new RuntimeException("Message lookup failed"));
var messageString = ruleMessageString.or(() -> globalMessageString).orElseThrow(() -> new SarifFormatException("Message lookup failed"));
return messageString.getText();
}

Expand Down

0 comments on commit 1d248cf

Please sign in to comment.