From 446c15413bc342a5ea05f083a8d3dfa25dcab6a4 Mon Sep 17 00:00:00 2001 From: Thomas Jaeckle Date: Thu, 10 Dec 2020 13:15:13 +0100 Subject: [PATCH] [#903] improved cloudevents exception handling * missing specversion lead to 500 error * exception texts were improved Signed-off-by: Thomas Jaeckle --- .../CloudEventMissingPayloadException.java | 4 +- .../CloudEventNotParsableException.java | 8 ++-- ...udEventUnsupportedDataSchemaException.java | 6 ++- .../routes/cloudevents/CloudEventsRoute.java | 43 +++++++++---------- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventMissingPayloadException.java b/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventMissingPayloadException.java index 6880b1ca47..0db67c9821 100644 --- a/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventMissingPayloadException.java +++ b/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventMissingPayloadException.java @@ -37,8 +37,8 @@ public final class CloudEventMissingPayloadException extends DittoRuntimeExcepti */ public static final String ERROR_CODE = "cloudevent.payload.missing"; - private static final String DEFAULT_MESSAGE = "The cloud event's payload is missing."; - private static final String DEFAULT_DESCRIPTION = "Ensure to provide payload in the cloud event."; + private static final String DEFAULT_MESSAGE = "The Cloud Event's payload is missing."; + private static final String DEFAULT_DESCRIPTION = "Ensure to provide payload in the Cloud Event."; private static final HttpStatusCode STATUS_CODE = HttpStatusCode.BAD_REQUEST; diff --git a/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventNotParsableException.java b/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventNotParsableException.java index 06810d1401..922584c30f 100644 --- a/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventNotParsableException.java +++ b/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventNotParsableException.java @@ -38,10 +38,10 @@ public final class CloudEventNotParsableException extends DittoRuntimeException */ public static final String ERROR_CODE = "cloudevent.unparsable"; - private static final String DEFAULT_MESSAGE = "The event could not be parsed."; - private static final String MESSAGE_PATTERN = "The system was unable to parse the event: {0}"; - private static final String DESCRIPTION = - "Ensure that the event is being transmitted according to the Cloud Events HTTP binding specification v1.0."; + private static final String DEFAULT_MESSAGE = "Unable to parse as Cloud Event."; + private static final String MESSAGE_PATTERN = "Unable to parse as Cloud Event because of: <{0}>"; + private static final String DESCRIPTION = "Ensure that the event is being transmitted according to the " + + "Cloud Events HTTP binding specification v1.0 and that all mandatory headers were set."; private static final URI DEFAULT_URI = URI.create("https://github.com/cloudevents/spec/blob/v1.0/http-protocol-binding.md"); diff --git a/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventUnsupportedDataSchemaException.java b/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventUnsupportedDataSchemaException.java index 8117dfc6d8..4ccd83b103 100644 --- a/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventUnsupportedDataSchemaException.java +++ b/model/base/src/main/java/org/eclipse/ditto/model/base/exceptions/CloudEventUnsupportedDataSchemaException.java @@ -38,8 +38,10 @@ public final class CloudEventUnsupportedDataSchemaException extends DittoRuntime */ public static final String ERROR_CODE = "cloudevent.dataschema.unsupported"; - private static final String DEFAULT_MESSAGE = "The data schema is not supported."; - private static final String MESSAGE_PATTERN = "The data schema <{0}> is not supported for this resource."; + private static final String DEFAULT_MESSAGE = "The provided Cloud Event dataschema is not supported for this " + + "resource."; + private static final String MESSAGE_PATTERN = "The provided Cloud Event dataschema <{0}> is not supported for " + + "this resource."; private static final String DESCRIPTION = "Ensure that the URI's scheme is 'ditto', so the complete dataschema " + "starts with 'ditto:'"; diff --git a/services/gateway/endpoints/src/main/java/org/eclipse/ditto/services/gateway/endpoints/routes/cloudevents/CloudEventsRoute.java b/services/gateway/endpoints/src/main/java/org/eclipse/ditto/services/gateway/endpoints/routes/cloudevents/CloudEventsRoute.java index e96bba302b..0643649725 100755 --- a/services/gateway/endpoints/src/main/java/org/eclipse/ditto/services/gateway/endpoints/routes/cloudevents/CloudEventsRoute.java +++ b/services/gateway/endpoints/src/main/java/org/eclipse/ditto/services/gateway/endpoints/routes/cloudevents/CloudEventsRoute.java @@ -187,29 +187,28 @@ private CloudEvent toCloudEvent(final RequestContext ctx, final DittoHeaders dit .trace("CloudEvent Ditto Headers: {}", dittoHeaders); } - // create a reader for the message - final MessageReader reader = HttpMessageFactory.createReader(acceptor -> { - - // NOTE: this acceptor may be run multiple times by the message reader - - // record if we saw the content type header - final AtomicBoolean sawContentType = new AtomicBoolean(); - // consume the HTTP request headers - ctx.getRequest().getHeaders().forEach(header -> { - if (header.lowercaseName().equals(DittoHeaderDefinition.CONTENT_TYPE.getKey())) { - sawContentType.set(true); - } - acceptor.accept(header.name(), header.value()); - }); - - if (!sawContentType.get()) { - // we didn't see the content type in the header, so extract it from akka's request - acceptor.accept(DittoHeaderDefinition.CONTENT_TYPE.getKey(), - ctx.getRequest().entity().getContentType().mediaType().toString()); - } - }, payload.toArray()); - try { + // create a reader for the message + final MessageReader reader = HttpMessageFactory.createReader(acceptor -> { + + // NOTE: this acceptor may be run multiple times by the message reader + + // record if we saw the content type header + final AtomicBoolean sawContentType = new AtomicBoolean(); + // consume the HTTP request headers + ctx.getRequest().getHeaders().forEach(header -> { + if (header.lowercaseName().equals(DittoHeaderDefinition.CONTENT_TYPE.getKey())) { + sawContentType.set(true); + } + acceptor.accept(header.name(), header.value()); + }); + + if (!sawContentType.get()) { + // we didn't see the content type in the header, so extract it from akka's request + acceptor.accept(DittoHeaderDefinition.CONTENT_TYPE.getKey(), + ctx.getRequest().entity().getContentType().mediaType().toString()); + } + }, payload.toArray()); return reader.toEvent(); } catch (final CloudEventRWException | IllegalStateException e) { throw CloudEventNotParsableException.withDetailedInformationBuilder(e.getMessage())