From ad2bf070197f1ebc9a2d3806a9380fe6958f0093 Mon Sep 17 00:00:00 2001 From: olavtar <94576904+olavtar@users.noreply.github.com> Date: Tue, 16 Apr 2024 06:14:06 -0700 Subject: [PATCH] feat: grouping exceptions with the same messages for glitchtip (#330) * feat: grouping exceptions with the same messages for glitchtip Signed-off-by: Olga Lavtar * feat: grouping exceptions with the same messages for glitchtip Signed-off-by: Olga Lavtar * fix: fixed the progress bar color to match the severity label colors (#331) Signed-off-by: Olga Lavtar * feat: grouping exceptions with the same messages for glitchtip Signed-off-by: Olga Lavtar --------- Signed-off-by: Olga Lavtar --- .../exception/ClientDetailedException.java | 50 +++++++++++++++++++ .../CycloneDXValidationException.java | 27 ++++++++++ .../config/exception/DetailedException.java | 36 +++++++++++++ .../exception/PackageValidationException.java | 25 ++++++++++ .../exception/SpdxParsingException.java | 27 ++++++++++ .../exception}/SpdxProcessingException.java | 8 ++- .../exception}/SpdxValidationException.java | 4 +- .../UnexpectedProviderException.java | 25 ++++++++++ .../backend/ExhortIntegration.java | 17 ++++++- .../sbom/cyclonedx/CycloneDxParser.java | 8 ++- .../backend/sbom/spdx/SpdxParser.java | 12 +++-- .../backend/sbom/spdx/SpdxWrapper.java | 6 ++- .../providers/ProviderResponseHandler.java | 6 ++- .../providers/VulnerabilityProvider.java | 3 +- .../providers/snyk/SnykIntegration.java | 3 +- .../providers/snyk/SnykRequestBuilder.java | 4 +- .../impl/SentryMonitoringClient.java | 9 ++++ .../backend/sbom/SbomParserTest.java | 5 +- .../backend/sbom/SpdxWrapperTest.java | 2 +- 19 files changed, 253 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/redhat/exhort/config/exception/ClientDetailedException.java create mode 100644 src/main/java/com/redhat/exhort/config/exception/CycloneDXValidationException.java create mode 100644 src/main/java/com/redhat/exhort/config/exception/DetailedException.java create mode 100644 src/main/java/com/redhat/exhort/config/exception/PackageValidationException.java create mode 100644 src/main/java/com/redhat/exhort/config/exception/SpdxParsingException.java rename src/main/java/com/redhat/exhort/{integration/backend/sbom/spdx => config/exception}/SpdxProcessingException.java (81%) rename src/main/java/com/redhat/exhort/{integration/backend/sbom/spdx => config/exception}/SpdxValidationException.java (88%) create mode 100644 src/main/java/com/redhat/exhort/config/exception/UnexpectedProviderException.java diff --git a/src/main/java/com/redhat/exhort/config/exception/ClientDetailedException.java b/src/main/java/com/redhat/exhort/config/exception/ClientDetailedException.java new file mode 100644 index 00000000..cb303de5 --- /dev/null +++ b/src/main/java/com/redhat/exhort/config/exception/ClientDetailedException.java @@ -0,0 +1,50 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.redhat.exhort.config.exception; + +import jakarta.ws.rs.core.Response.Status; + +public class ClientDetailedException extends DetailedException { + private Status status; + + public ClientDetailedException(String message) { + super(message, null); + } + + public ClientDetailedException(String message, String details) { + super(message, details); + } + + public ClientDetailedException(Throwable e) { + super(e.getMessage(), null); + } + + public ClientDetailedException(String message, Throwable e) { + super(message, e.getMessage()); + } + + public ClientDetailedException(String message, String details, Status status) { + super(message, details); + this.status = status; + } + + public String getStatus() { + return String.valueOf(status.getStatusCode()); + } +} diff --git a/src/main/java/com/redhat/exhort/config/exception/CycloneDXValidationException.java b/src/main/java/com/redhat/exhort/config/exception/CycloneDXValidationException.java new file mode 100644 index 00000000..e83799e6 --- /dev/null +++ b/src/main/java/com/redhat/exhort/config/exception/CycloneDXValidationException.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.redhat.exhort.config.exception; + +import jakarta.ws.rs.core.Response.Status; + +public class CycloneDXValidationException extends ClientDetailedException { + public CycloneDXValidationException(Exception e, Status status) { + super("CycloneDX Validation error", e.getMessage(), status); + } +} diff --git a/src/main/java/com/redhat/exhort/config/exception/DetailedException.java b/src/main/java/com/redhat/exhort/config/exception/DetailedException.java new file mode 100644 index 00000000..09c652c7 --- /dev/null +++ b/src/main/java/com/redhat/exhort/config/exception/DetailedException.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.redhat.exhort.config.exception; + +public class DetailedException extends RuntimeException { + private final String details; + + public DetailedException(String message, String details) { + super(message); + this.details = details; + } + + public String getDetails() { + return details; + } + + public String getStatus() { + return "422"; + } +} diff --git a/src/main/java/com/redhat/exhort/config/exception/PackageValidationException.java b/src/main/java/com/redhat/exhort/config/exception/PackageValidationException.java new file mode 100644 index 00000000..507683cb --- /dev/null +++ b/src/main/java/com/redhat/exhort/config/exception/PackageValidationException.java @@ -0,0 +1,25 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.redhat.exhort.config.exception; + +public class PackageValidationException extends DetailedException { + public PackageValidationException(Exception e) { + super("Package version must not be null", e.getMessage()); + } +} diff --git a/src/main/java/com/redhat/exhort/config/exception/SpdxParsingException.java b/src/main/java/com/redhat/exhort/config/exception/SpdxParsingException.java new file mode 100644 index 00000000..369417a2 --- /dev/null +++ b/src/main/java/com/redhat/exhort/config/exception/SpdxParsingException.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.redhat.exhort.config.exception; + +import jakarta.ws.rs.core.Response.Status; + +public class SpdxParsingException extends ClientDetailedException { + public SpdxParsingException(Exception e, Status status) { + super(e.getMessage(), e.getMessage(), status); + } +} diff --git a/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxProcessingException.java b/src/main/java/com/redhat/exhort/config/exception/SpdxProcessingException.java similarity index 81% rename from src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxProcessingException.java rename to src/main/java/com/redhat/exhort/config/exception/SpdxProcessingException.java index 2adbefd3..b65e55b8 100644 --- a/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxProcessingException.java +++ b/src/main/java/com/redhat/exhort/config/exception/SpdxProcessingException.java @@ -16,9 +16,9 @@ * limitations under the License. */ -package com.redhat.exhort.integration.backend.sbom.spdx; +package com.redhat.exhort.config.exception; -public class SpdxProcessingException extends RuntimeException { +public class SpdxProcessingException extends ClientDetailedException { public SpdxProcessingException(String msg) { super(msg); @@ -31,4 +31,8 @@ public SpdxProcessingException(Throwable e) { public SpdxProcessingException(String msg, Throwable e) { super(msg, e); } + + public SpdxProcessingException(String msg, String details) { + super(msg, details); + } } diff --git a/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxValidationException.java b/src/main/java/com/redhat/exhort/config/exception/SpdxValidationException.java similarity index 88% rename from src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxValidationException.java rename to src/main/java/com/redhat/exhort/config/exception/SpdxValidationException.java index 41e1cd6e..e118e1dd 100644 --- a/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxValidationException.java +++ b/src/main/java/com/redhat/exhort/config/exception/SpdxValidationException.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package com.redhat.exhort.integration.backend.sbom.spdx; +package com.redhat.exhort.config.exception; import java.util.List; @@ -25,7 +25,7 @@ public class SpdxValidationException extends SpdxProcessingException { private final List errors; public SpdxValidationException(String expectedVersion, List errors) { - super(expectedVersion + " Validation error. " + errors.toString()); + super(expectedVersion + " Validation error", errors.toString()); this.errors = errors; } diff --git a/src/main/java/com/redhat/exhort/config/exception/UnexpectedProviderException.java b/src/main/java/com/redhat/exhort/config/exception/UnexpectedProviderException.java new file mode 100644 index 00000000..e2ef59f4 --- /dev/null +++ b/src/main/java/com/redhat/exhort/config/exception/UnexpectedProviderException.java @@ -0,0 +1,25 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.redhat.exhort.config.exception; + +public class UnexpectedProviderException extends DetailedException { + public UnexpectedProviderException(Exception e) { + super("Unexpected provider", e.getMessage()); + } +} diff --git a/src/main/java/com/redhat/exhort/integration/backend/ExhortIntegration.java b/src/main/java/com/redhat/exhort/integration/backend/ExhortIntegration.java index f2dcc14e..d9d5fb2a 100644 --- a/src/main/java/com/redhat/exhort/integration/backend/ExhortIntegration.java +++ b/src/main/java/com/redhat/exhort/integration/backend/ExhortIntegration.java @@ -48,6 +48,7 @@ import com.redhat.exhort.analytics.AnalyticsService; import com.redhat.exhort.api.PackageRef; import com.redhat.exhort.api.v4.AnalysisReport; +import com.redhat.exhort.config.exception.DetailedException; import com.redhat.exhort.integration.Constants; import com.redhat.exhort.integration.backend.sbom.SbomParser; import com.redhat.exhort.integration.backend.sbom.SbomParserFactory; @@ -113,7 +114,7 @@ public void configure() { .handled(true) .setBody().simple("${exception.message}"); - onException(ClientErrorException.class) + onException(ClientErrorException.class, DetailedException.class) .routeId("onExhortClientErrorException") .useOriginalMessage() .process(monitoringProcessor::processClientException) @@ -127,6 +128,20 @@ public void configure() { .setHeader(Exchange.CONTENT_ENCODING, constant("gzip")) .end(); + onException(DetailedException.class) + .routeId("onExhortDetailedException") + .useOriginalMessage() + .process(monitoringProcessor::processClientException) + .setHeader(Exchange.HTTP_RESPONSE_CODE, simple("${exception.getStatus()}")) + .setHeader(Exchange.CONTENT_TYPE, constant(MediaType.TEXT_PLAIN)) + .setHeader(Constants.EXHORT_REQUEST_ID_HEADER, exchangeProperty(Constants.EXHORT_REQUEST_ID_HEADER)) + .handled(true) + .setBody().simple("${exception.message}") + .choice() + .when(exchangeProperty(Constants.GZIP_RESPONSE_PROPERTY).isNotNull()).marshal().gzipDeflater() + .setHeader(Exchange.CONTENT_ENCODING, constant("gzip")) + .end(); + rest() .post("/v3/analysis") .routeId("v3restAnalysis") diff --git a/src/main/java/com/redhat/exhort/integration/backend/sbom/cyclonedx/CycloneDxParser.java b/src/main/java/com/redhat/exhort/integration/backend/sbom/cyclonedx/CycloneDxParser.java index 3afe549f..3e5ef90e 100644 --- a/src/main/java/com/redhat/exhort/integration/backend/sbom/cyclonedx/CycloneDxParser.java +++ b/src/main/java/com/redhat/exhort/integration/backend/sbom/cyclonedx/CycloneDxParser.java @@ -42,11 +42,11 @@ import com.networknt.schema.ValidationMessage; import com.redhat.exhort.api.PackageRef; import com.redhat.exhort.config.ObjectMapperProducer; +import com.redhat.exhort.config.exception.CycloneDXValidationException; import com.redhat.exhort.integration.backend.sbom.SbomParser; import com.redhat.exhort.model.DependencyTree; import com.redhat.exhort.model.DirectDependency; -import jakarta.ws.rs.ClientErrorException; import jakarta.ws.rs.core.Response; public class CycloneDxParser extends SbomParser { @@ -186,12 +186,10 @@ private Bom parseBom(InputStream input) { return bom; } catch (ParseException e) { LOGGER.debug("CycloneDX Validation error: ", e); - throw new ClientErrorException( - "CycloneDX Validation error: " + e.getMessage(), Response.Status.BAD_REQUEST); + throw new CycloneDXValidationException(e, Response.Status.BAD_REQUEST); } catch (IOException e) { LOGGER.error("CycloneDX Validation error: ", e); - throw new ClientErrorException( - "CycloneDX Validation error: " + e.getMessage(), Response.Status.BAD_REQUEST); + throw new CycloneDXValidationException(e, Response.Status.BAD_REQUEST); } } diff --git a/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxParser.java b/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxParser.java index 78b67565..092c76ea 100644 --- a/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxParser.java +++ b/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxParser.java @@ -37,11 +37,14 @@ import org.spdx.storage.simple.InMemSpdxStore; import com.redhat.exhort.api.PackageRef; +import com.redhat.exhort.config.exception.ClientDetailedException; +import com.redhat.exhort.config.exception.SpdxParsingException; +import com.redhat.exhort.config.exception.SpdxProcessingException; +import com.redhat.exhort.config.exception.SpdxValidationException; import com.redhat.exhort.integration.backend.sbom.SbomParser; import com.redhat.exhort.model.DependencyTree; import com.redhat.exhort.model.DirectDependency; -import jakarta.ws.rs.ClientErrorException; import jakarta.ws.rs.core.Response; public class SpdxParser extends SbomParser { @@ -58,12 +61,11 @@ protected DependencyTree buildTree(InputStream input) { return tree; } catch (SpdxValidationException e) { LOGGER.info("Invalid SPDX SBOM received", e); - throw new ClientErrorException(e.getMessage(), Response.Status.BAD_REQUEST); + throw new SpdxParsingException(e, Response.Status.BAD_REQUEST); } catch (SpdxProcessingException | InvalidSPDXAnalysisException | IOException e) { LOGGER.warn("Unable to parse the SPDX SBOM file", e); - throw new ClientErrorException( - "Unable to parse received SPDX SBOM file: " + e.getMessage(), - Response.Status.BAD_REQUEST); + throw new ClientDetailedException( + "Unable to parse the SPDX SBOM file", e.getMessage(), Response.Status.BAD_REQUEST); } } diff --git a/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxWrapper.java b/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxWrapper.java index 3094c889..60f496b2 100644 --- a/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxWrapper.java +++ b/src/main/java/com/redhat/exhort/integration/backend/sbom/spdx/SpdxWrapper.java @@ -33,6 +33,8 @@ import org.spdx.library.model.TypedValue; import com.redhat.exhort.api.PackageRef; +import com.redhat.exhort.config.exception.SpdxProcessingException; +import com.redhat.exhort.config.exception.SpdxValidationException; public class SpdxWrapper { @@ -76,8 +78,8 @@ public PackageRef toPackageRef(SpdxPackage spdxPackage) { .findFirst(); if (ref.isEmpty()) { throw new SpdxProcessingException( - "Missing Purl External Reference for Package: " - + spdxPackage.getName().orElse("unknown")); + "Missing Purl External Reference for Package", + "Package name: " + spdxPackage.getName().orElse("unknown")); } return new PackageRef(ref.get().getReferenceLocator()); } catch (InvalidSPDXAnalysisException e) { diff --git a/src/main/java/com/redhat/exhort/integration/providers/ProviderResponseHandler.java b/src/main/java/com/redhat/exhort/integration/providers/ProviderResponseHandler.java index 4ac503a1..7cb33b0d 100644 --- a/src/main/java/com/redhat/exhort/integration/providers/ProviderResponseHandler.java +++ b/src/main/java/com/redhat/exhort/integration/providers/ProviderResponseHandler.java @@ -47,6 +47,8 @@ import com.redhat.exhort.api.v4.SourceSummary; import com.redhat.exhort.api.v4.TransitiveDependencyReport; import com.redhat.exhort.api.v4.UnscannedDependency; +import com.redhat.exhort.config.exception.PackageValidationException; +import com.redhat.exhort.config.exception.UnexpectedProviderException; import com.redhat.exhort.integration.Constants; import com.redhat.exhort.model.CvssScoreComparable.DependencyScoreComparator; import com.redhat.exhort.model.CvssScoreComparable.TransitiveScoreComparator; @@ -171,7 +173,9 @@ public void processResponseError(Exchange exchange) { String message = prettifyHttpError(httpException); status.message(message).code(httpException.getStatusCode()); LOGGER.warn("Unable to process request: {}", message, cause); - } else if (cause instanceof IllegalArgumentException) { + } else if (cause instanceof IllegalArgumentException + || cause instanceof UnexpectedProviderException + || cause instanceof PackageValidationException) { status.message(cause.getMessage()).code(422); LOGGER.debug("Unable to process request to: {}", getProviderName(), exception); } else { diff --git a/src/main/java/com/redhat/exhort/integration/providers/VulnerabilityProvider.java b/src/main/java/com/redhat/exhort/integration/providers/VulnerabilityProvider.java index 65b4aa44..cd64a3c0 100644 --- a/src/main/java/com/redhat/exhort/integration/providers/VulnerabilityProvider.java +++ b/src/main/java/com/redhat/exhort/integration/providers/VulnerabilityProvider.java @@ -32,6 +32,7 @@ import org.apache.camel.util.URISupport; import org.eclipse.microprofile.config.inject.ConfigProperty; +import com.redhat.exhort.config.exception.UnexpectedProviderException; import com.redhat.exhort.integration.Constants; import io.quarkus.runtime.annotations.RegisterForReflection; @@ -79,7 +80,7 @@ public List getProviderEndpoints( case Constants.SNYK_PROVIDER -> "direct:snykScan"; case Constants.OSS_INDEX_PROVIDER -> "direct:ossIndexScan"; case Constants.OSV_NVD_PROVIDER -> "direct:osvNvdScan"; - default -> throw new IllegalArgumentException("Unexpected provider: " + p); + default -> throw new UnexpectedProviderException(new RuntimeException(p)); }) .collect(Collectors.toList()); } diff --git a/src/main/java/com/redhat/exhort/integration/providers/snyk/SnykIntegration.java b/src/main/java/com/redhat/exhort/integration/providers/snyk/SnykIntegration.java index 643b152e..8a8647d6 100644 --- a/src/main/java/com/redhat/exhort/integration/providers/snyk/SnykIntegration.java +++ b/src/main/java/com/redhat/exhort/integration/providers/snyk/SnykIntegration.java @@ -26,6 +26,7 @@ import org.apache.camel.builder.endpoint.EndpointRouteBuilder; import org.eclipse.microprofile.config.inject.ConfigProperty; +import com.redhat.exhort.config.exception.DetailedException; import com.redhat.exhort.integration.Constants; import com.redhat.exhort.integration.providers.VulnerabilityProvider; import com.redhat.exhort.monitoring.MonitoringProcessor; @@ -60,7 +61,7 @@ public class SnykIntegration extends EndpointRouteBuilder { public void configure() { // fmt:off - onException(IllegalArgumentException.class) + onException(IllegalArgumentException.class, DetailedException.class) .routeId("snykIllegalArgumentException") .useOriginalMessage() .handled(true) diff --git a/src/main/java/com/redhat/exhort/integration/providers/snyk/SnykRequestBuilder.java b/src/main/java/com/redhat/exhort/integration/providers/snyk/SnykRequestBuilder.java index 46ab4ec1..a0872595 100644 --- a/src/main/java/com/redhat/exhort/integration/providers/snyk/SnykRequestBuilder.java +++ b/src/main/java/com/redhat/exhort/integration/providers/snyk/SnykRequestBuilder.java @@ -42,6 +42,7 @@ import com.redhat.exhort.api.PackageRef; import com.redhat.exhort.api.v4.UnscannedDependency; import com.redhat.exhort.config.ObjectMapperProducer; +import com.redhat.exhort.config.exception.PackageValidationException; import com.redhat.exhort.integration.Constants; import com.redhat.exhort.model.DependencyTree; @@ -98,7 +99,8 @@ public static void validate(Exchange exchange) { tree.forEach( d -> { if (d.purl().getVersion() == null) { - throw new IllegalArgumentException("Version must not be null for package: " + d.purl()); + String errorMessage = "Package: " + d.purl(); + throw new PackageValidationException(new RuntimeException(errorMessage)); } types.add(d.purl().getType()); }); diff --git a/src/main/java/com/redhat/exhort/monitoring/impl/SentryMonitoringClient.java b/src/main/java/com/redhat/exhort/monitoring/impl/SentryMonitoringClient.java index a89c914b..e5010989 100644 --- a/src/main/java/com/redhat/exhort/monitoring/impl/SentryMonitoringClient.java +++ b/src/main/java/com/redhat/exhort/monitoring/impl/SentryMonitoringClient.java @@ -20,6 +20,7 @@ import java.util.Map; +import com.redhat.exhort.config.exception.DetailedException; import com.redhat.exhort.monitoring.MonitoringClient; import com.redhat.exhort.monitoring.MonitoringContext; @@ -47,6 +48,14 @@ public void reportException(Throwable exception, MonitoringContext context) { hub.setUser(user); } addAdditionalData(hub, context.metadata(), context.tags()); + + if (exception instanceof DetailedException) { + DetailedException detailedException = (DetailedException) exception; + String details = detailedException.getDetails(); + if (details != null) { + hub.setExtra("Error details", details); + } + } hub.captureException(exception); } diff --git a/src/test/java/com/redhat/exhort/integration/backend/sbom/SbomParserTest.java b/src/test/java/com/redhat/exhort/integration/backend/sbom/SbomParserTest.java index f093dbea..a9c5e89b 100644 --- a/src/test/java/com/redhat/exhort/integration/backend/sbom/SbomParserTest.java +++ b/src/test/java/com/redhat/exhort/integration/backend/sbom/SbomParserTest.java @@ -35,6 +35,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import com.redhat.exhort.config.exception.ClientDetailedException; import com.redhat.exhort.integration.Constants; import com.redhat.exhort.integration.backend.sbom.cyclonedx.CycloneDxParser; import com.redhat.exhort.integration.backend.sbom.spdx.SpdxParser; @@ -99,9 +100,9 @@ void testSBOMWithoutDependencies(String mediaType) { void testParseInvalidSBOM(String mediaType) { var parser = SbomParserFactory.newInstance(mediaType); var file = getClass().getClassLoader().getResourceAsStream("invalid_deps_file.txt"); - var ex = assertThrows(ClientErrorException.class, () -> parser.buildTree(file)); + var ex = assertThrows(ClientDetailedException.class, () -> parser.buildTree(file)); assertNotNull(ex); - assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), ex.getResponse().getStatus()); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), Integer.valueOf(ex.getStatus())); } @ParameterizedTest diff --git a/src/test/java/com/redhat/exhort/integration/backend/sbom/SpdxWrapperTest.java b/src/test/java/com/redhat/exhort/integration/backend/sbom/SpdxWrapperTest.java index 4b70449b..b988483d 100644 --- a/src/test/java/com/redhat/exhort/integration/backend/sbom/SpdxWrapperTest.java +++ b/src/test/java/com/redhat/exhort/integration/backend/sbom/SpdxWrapperTest.java @@ -32,7 +32,7 @@ import org.spdx.library.Version; import org.spdx.storage.simple.InMemSpdxStore; -import com.redhat.exhort.integration.backend.sbom.spdx.SpdxProcessingException; +import com.redhat.exhort.config.exception.SpdxProcessingException; import com.redhat.exhort.integration.backend.sbom.spdx.SpdxWrapper; public class SpdxWrapperTest {