Skip to content

Commit

Permalink
fix(irs-api):[#538] add deep search for exception cause
Browse files Browse the repository at this point in the history
  • Loading branch information
ds-jhartmann committed Jul 15, 2024
1 parent 6a0ba2a commit 0e9b5fe
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ void shouldCreateDetailedTombstoneForMissmatchPolicy() {
final Tombstone actualTombstone = jobForJobId.getTombstones().get(0);
assertThat(actualTombstone.getProcessingError().getRootCauses()).hasSize(1);
assertThat(actualTombstone.getProcessingError().getRootCauses().get(0)).contains(
"Asset could not be negotiated for providerWithSuffix 'https://test.edc.io/api/v1/dsp', BPN 'BPNL00000000TEST', catalogItem");
"UsagePolicyPermissionException: Policies [default-policy] did not match with policy from BPNL00000000TEST.");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void shouldUseSuppressedExceptionWhenPresent() {

// assert
assertThat(from.getProcessingError().getErrorDetail()).isEqualTo(exception.getMessage());
assertThat(from.getProcessingError().getRootCauses()).contains(suppressedExceptionMessage);
assertThat(from.getProcessingError().getRootCauses()).contains("Exception: " + suppressedExceptionMessage);
}

@Test
Expand All @@ -93,7 +93,8 @@ void shouldUseDeepSuppressedExceptionWhenPresent() {
final Exception exception = new Exception("Exception occurred.");

final Exception rootCause = new Exception("Wrapper exception to the root cause");
rootCause.addSuppressed(new Exception("Root cause of the exception"));
final String suppressedRootCause = "Root cause of the exception";
rootCause.addSuppressed(new Exception(suppressedRootCause));

final Exception suppressedWrapperException = new Exception(
"Suppressed Exception which was added through Futures.", rootCause);
Expand All @@ -107,7 +108,7 @@ void shouldUseDeepSuppressedExceptionWhenPresent() {

// assert
assertThat(from.getProcessingError().getErrorDetail()).isEqualTo(exception.getMessage());
assertThat(from.getProcessingError().getRootCauses()).contains("Root cause of the exception");
assertThat(from.getProcessingError().getRootCauses()).contains("Exception: " + suppressedRootCause);
}

@Test
Expand Down
5 changes: 5 additions & 0 deletions irs-models/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;
import lombok.extern.jackson.Jacksonized;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.eclipse.tractusx.irs.component.enums.NodeType;
import org.eclipse.tractusx.irs.component.enums.ProcessStep;

Expand Down Expand Up @@ -88,8 +88,8 @@ public static Tombstone from(final String catenaXId, final String endpointURL, f

public static Tombstone from(final String globalAssetId, final String endpointURL, final Throwable exception,
final Throwable[] suppressed, final int retryCount, final ProcessStep processStep) {
final ProcessingError processingError =
withProcessingError(processStep, retryCount, exception.getMessage(), suppressed);
final ProcessingError processingError = withProcessingError(processStep, retryCount, exception.getMessage(),
suppressed);
return Tombstone.builder()
.endpointURL(endpointURL)
.catenaXId(globalAssetId)
Expand All @@ -99,7 +99,7 @@ public static Tombstone from(final String globalAssetId, final String endpointUR

private static ProcessingError withProcessingError(final ProcessStep processStep, final int retryCount,
final String message, final Throwable... suppressed) {
final List<String> rootCauses = Arrays.stream(suppressed).flatMap(Tombstone::getErrorMessages).toList();
final List<String> rootCauses = Arrays.stream(suppressed).map(Tombstone::getRootErrorMessages).toList();

return ProcessingError.builder()
.withProcessStep(processStep)
Expand All @@ -110,12 +110,30 @@ private static ProcessingError withProcessingError(final ProcessStep processStep
.build();
}

private static Stream<String> getErrorMessages(final Throwable throwable) {
/**
* Search for the root cause or suppressed exception as long as there is a cause or suppressed exception.
* Stop after a depth of 10 to prevent endless loop.
*
* @param throwable the exception with a nested or suppressed exception
* @return the root cause, eiter suppressed or nested
*/
private static String getRootErrorMessages(final Throwable throwable) {
final Throwable cause = throwable.getCause();
if (cause != null && hasSuppressedExceptions(cause)) {
return Arrays.stream(throwable.getCause().getSuppressed()).map(Throwable::getMessage);

if (cause != null) {
Throwable rootCause = cause;
int depth = 0;
while (rootCause.getCause() != null || hasSuppressedExceptions(rootCause) || depth > 10) {
if (hasSuppressedExceptions(rootCause)) {
rootCause = rootCause.getSuppressed()[0];
} else {
rootCause = rootCause.getCause();
}
depth++;
}
return ExceptionUtils.getRootCauseMessage(rootCause);
}
return Stream.of(throwable.getMessage());
return ExceptionUtils.getRootCauseMessage(throwable);
}

private static ProcessingError withProcessingError(final ProcessStep processStep, final int retryCount,
Expand Down

0 comments on commit 0e9b5fe

Please sign in to comment.