Skip to content

Commit

Permalink
added new DittoInternalErrorException and used whereever GatewayInter…
Browse files Browse the repository at this point in the history
…nalErrorException was used without "gateway" scope

* fixed handling of DittoRuntimeExceptions in AbstractPersistecenSupervisor

Signed-off-by: Thomas Jaeckle <thomas.jaeckle@bosch.io>
  • Loading branch information
thjaeckle committed May 2, 2022
1 parent ba2f36e commit 3b27fba
Show file tree
Hide file tree
Showing 26 changed files with 238 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.ditto.base.model.signals.commands.exceptions;

import java.net.URI;

import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;

import org.eclipse.ditto.base.model.common.HttpStatus;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeExceptionBuilder;
import org.eclipse.ditto.base.model.headers.DittoHeaders;
import org.eclipse.ditto.base.model.json.JsonParsableException;
import org.eclipse.ditto.json.JsonObject;

/**
* This exception indicates that an unexpected internal error occurred in a Ditto service.
* @since 3.0.0
*/
@Immutable
@JsonParsableException(errorCode = DittoInternalErrorException.ERROR_CODE)
public final class DittoInternalErrorException extends DittoRuntimeException implements GeneralException {

/**
* Error code of this exception.
*/
public static final String ERROR_CODE = ERROR_CODE_PREFIX + "internalerror";

private static final String DEFAULT_MESSAGE = "There was a rare case of an unexpected internal error.";
private static final String DEFAULT_DESCRIPTION = "Please contact the service team or your administrator.";

private static final long serialVersionUID = 927151443229985012L;

private DittoInternalErrorException(final DittoHeaders dittoHeaders,
@Nullable final String message,
@Nullable final String description,
@Nullable final Throwable cause,
@Nullable final URI href) {
super(ERROR_CODE, HttpStatus.INTERNAL_SERVER_ERROR, dittoHeaders, message, description, cause, href);
}

/**
* A mutable builder for a {@code DittoInternalErrorException}.
*
* @return the builder.
*/
public static Builder newBuilder() {
return new Builder();
}

/**
* Constructs a new {@code DittoInternalErrorException} object with given message.
*
* @param message detail message. This message can be later retrieved by the {@link #getMessage()} method.
* @param dittoHeaders the headers of the command which resulted in this exception.
* @return the new DittoInternalErrorException.
* @throws NullPointerException if {@code dittoHeaders} is {@code null}.
*/
public static DittoInternalErrorException fromMessage(@Nullable final String message,
final DittoHeaders dittoHeaders) {
return DittoRuntimeException.fromMessage(message, dittoHeaders, new Builder());
}

/**
* Constructs a new {@code DittoInternalErrorException} object with the exception message extracted from the given
* JSON object.
*
* @param jsonObject the JSON to read the {@link org.eclipse.ditto.base.model.exceptions.DittoRuntimeException.JsonFields#MESSAGE} field from.
* @param dittoHeaders the headers of the command which resulted in this exception.
* @return the new DittoInternalErrorException.
* @throws NullPointerException if any argument is {@code null}.
* @throws org.eclipse.ditto.json.JsonMissingFieldException if this JsonObject did not contain an error message.
* @throws org.eclipse.ditto.json.JsonParseException if the passed in {@code jsonObject} was not in the expected
* format.
*/
public static DittoInternalErrorException fromJson(final JsonObject jsonObject,
final DittoHeaders dittoHeaders) {
return DittoRuntimeException.fromJson(jsonObject, dittoHeaders, new Builder());
}

@Override
public DittoRuntimeException setDittoHeaders(final DittoHeaders dittoHeaders) {
return new Builder()
.message(getMessage())
.description(getDescription().orElse(null))
.cause(getCause())
.href(getHref().orElse(null))
.dittoHeaders(dittoHeaders)
.build();
}

/**
* A mutable builder with a fluent API for a {@link org.eclipse.ditto.base.model.signals.commands.exceptions.DittoInternalErrorException}.
*/
@NotThreadSafe
public static final class Builder extends DittoRuntimeExceptionBuilder<DittoInternalErrorException> {

private Builder() {
message(DEFAULT_MESSAGE);
description(DEFAULT_DESCRIPTION);
}

@Override
protected DittoInternalErrorException doBuild(final DittoHeaders dittoHeaders,
@Nullable final String message,
@Nullable final String description,
@Nullable final Throwable cause,
@Nullable final URI href) {
return new DittoInternalErrorException(dittoHeaders, message, description, cause, href);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;

import org.eclipse.ditto.json.JsonObject;
import org.eclipse.ditto.base.model.common.HttpStatus;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeExceptionBuilder;
import org.eclipse.ditto.base.model.headers.DittoHeaders;
import org.eclipse.ditto.base.model.json.JsonParsableException;
import org.eclipse.ditto.json.JsonObject;

/**
* This exception indicates that a request contains a reference placeholder which references an unsupported entity type.
* TODO TJ not a GatewayException
*/
@Immutable
@JsonParsableException(errorCode = GatewayPlaceholderReferenceNotSupportedException.ERROR_CODE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;

import org.eclipse.ditto.json.JsonObject;
import org.eclipse.ditto.base.model.common.HttpStatus;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeExceptionBuilder;
import org.eclipse.ditto.base.model.headers.DittoHeaders;
import org.eclipse.ditto.base.model.json.JsonParsableException;
import org.eclipse.ditto.json.JsonObject;

/**
* This exception indicates that a request contains a reference placeholder which references an unknown field on the referenced entity.
* TODO TJ not a GatewayException
*/
@Immutable
@JsonParsableException(errorCode = GatewayPlaceholderReferenceUnknownFieldException.ERROR_CODE)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.ditto.base.model.signals.commands.exceptions;

/**
* Aggregates all {@link org.eclipse.ditto.base.model.exceptions.DittoRuntimeException}s which are emitted by Ditto
* by any service, e.g. used for "internal error" exceptions.
* @since 3.0.0
*/
public interface GeneralException {

/**
* Error code prefix of errors emitted by any Ditto service.
*/
String ERROR_CODE_PREFIX = "general" + ":";

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;

import org.eclipse.ditto.json.JsonObject;
import org.eclipse.ditto.json.JsonPointer;
import org.eclipse.ditto.base.model.common.HttpStatus;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeExceptionBuilder;
import org.eclipse.ditto.base.model.headers.DittoHeaders;
import org.eclipse.ditto.base.model.json.JsonParsableException;
import org.eclipse.ditto.json.JsonObject;
import org.eclipse.ditto.json.JsonPointer;

/**
* Thrown if a path is not known for any existing command, response or event.
* TODO TJ not a GatewayException
*
* @since 2.0.0
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
import org.eclipse.ditto.base.model.signals.JsonTypeNotParsableException;
import org.eclipse.ditto.base.model.signals.commands.Command;
import org.eclipse.ditto.base.model.signals.commands.CommandResponse;
import org.eclipse.ditto.base.model.signals.commands.exceptions.GatewayInternalErrorException;
import org.eclipse.ditto.base.model.signals.commands.exceptions.DittoInternalErrorException;
import org.eclipse.ditto.internal.utils.akka.actors.RetrieveConfigBehavior;
import org.eclipse.ditto.internal.utils.akka.logging.DittoDiagnosticLoggingAdapter;
import org.eclipse.ditto.internal.utils.akka.logging.DittoLoggerFactory;
Expand Down Expand Up @@ -289,7 +289,7 @@ private void tryInterpretAsDirectPublication(final DevOpsCommand<?> command,
} else {
// this should not happen
final JsonObject error =
GatewayInternalErrorException.newBuilder().dittoHeaders(command.getDittoHeaders()).build().toJson();
DittoInternalErrorException.newBuilder().dittoHeaders(command.getDittoHeaders()).build().toJson();
onError.accept(getErrorResponse(command, error));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import org.eclipse.ditto.base.model.signals.commands.Command;
import org.eclipse.ditto.base.model.signals.commands.CommandResponse;
import org.eclipse.ditto.base.model.signals.commands.WithEntity;
import org.eclipse.ditto.base.model.signals.commands.exceptions.GatewayInternalErrorException;
import org.eclipse.ditto.base.model.signals.commands.exceptions.DittoInternalErrorException;
import org.eclipse.ditto.internal.utils.akka.logging.DittoDiagnosticLoggingAdapter;
import org.eclipse.ditto.internal.utils.akka.logging.DittoLoggerFactory;
import org.eclipse.ditto.internal.utils.metrics.DittoMetrics;
Expand Down Expand Up @@ -161,8 +161,8 @@ private void askTargetActor(final Command<?> command, final List<ThingId> thingI
log.error("Unexpected non-DittoRuntimeException error - responding with " +
"GatewayInternalErrorException. Cause: {} - {}",
response.getClass().getSimpleName(), response);
final GatewayInternalErrorException responseEx =
GatewayInternalErrorException.newBuilder()
final DittoInternalErrorException responseEx =
DittoInternalErrorException.newBuilder()
.dittoHeaders(command.getDittoHeaders())
.build();
sender.tell(responseEx, getSelf());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException;
import org.eclipse.ditto.base.model.headers.DittoHeaders;
import org.eclipse.ditto.base.model.signals.commands.exceptions.DittoInternalErrorException;
import org.eclipse.ditto.things.model.ThingId;
import org.eclipse.ditto.things.model.ThingIdInvalidException;
import org.eclipse.ditto.base.model.signals.commands.exceptions.GatewayInternalErrorException;
import org.eclipse.ditto.things.model.signals.commands.query.RetrieveThings;
import org.junit.AfterClass;
import org.junit.BeforeClass;
Expand All @@ -42,8 +42,8 @@ public final class ThingsAggregatorProxyActorTest {
ThingIdInvalidException.newBuilder("invalidThingId")
.dittoHeaders(DITTO_HEADERS)
.build();
private static final GatewayInternalErrorException GATEWAY_INTERNAL_ERROR_EXCEPTION =
GatewayInternalErrorException.newBuilder().dittoHeaders(DITTO_HEADERS).build();
private static final DittoInternalErrorException INTERNAL_ERROR_EXCEPTION =
DittoInternalErrorException.newBuilder().dittoHeaders(DITTO_HEADERS).build();
private static final RetrieveThings RETRIEVE_THINGS_COMMAND =
RetrieveThings.getBuilder(ThingId.of("ditto", "thing"))
.dittoHeaders(DITTO_HEADERS)
Expand All @@ -69,13 +69,13 @@ public void testHandleDittoRuntimeException() {
public void testHandleGenericException() {
new TestKit(actorSystem) {{
final TestProbe targetActor = new TestProbe(actorSystem);
targetActor.setAutoPilot(new AutoPilotAnsweringWithException(GATEWAY_INTERNAL_ERROR_EXCEPTION));
targetActor.setAutoPilot(new AutoPilotAnsweringWithException(INTERNAL_ERROR_EXCEPTION));

final Props props = ThingsAggregatorProxyActor.props(targetActor.ref());
final ActorRef proxyActor = actorSystem.actorOf(props);

proxyActor.tell(RETRIEVE_THINGS_COMMAND, getRef());
expectMsg(GATEWAY_INTERNAL_ERROR_EXCEPTION);
expectMsg(INTERNAL_ERROR_EXCEPTION);
}};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.eclipse.ditto.base.model.entity.id.WithEntityId;
import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException;
import org.eclipse.ditto.base.model.headers.WithDittoHeaders;
import org.eclipse.ditto.base.model.signals.commands.exceptions.GatewayInternalErrorException;
import org.eclipse.ditto.base.model.signals.commands.exceptions.DittoInternalErrorException;
import org.eclipse.ditto.internal.utils.akka.logging.DittoLoggerFactory;
import org.eclipse.ditto.internal.utils.akka.logging.ThreadSafeDittoLoggingAdapter;
import org.eclipse.ditto.internal.utils.metrics.DittoMetrics;
Expand Down Expand Up @@ -219,7 +219,7 @@ private Void incrementEnqueueCounters(final QueueOfferResult result, final Throw

private void handleUnknownThrowable(final Throwable unknownThrowable) {
logger.warning("Received unknown Throwable <{}>!", unknownThrowable);
final GatewayInternalErrorException gatewayInternalError = GatewayInternalErrorException.newBuilder()
final DittoInternalErrorException gatewayInternalError = DittoInternalErrorException.newBuilder()
.cause(unknownThrowable)
.build();
getSender().tell(gatewayInternalError, getSelf());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.eclipse.ditto.base.model.namespaces.signals.commands.UnblockNamespace;
import org.eclipse.ditto.base.model.namespaces.signals.commands.UnblockNamespaceResponse;
import org.eclipse.ditto.base.model.signals.commands.Command;
import org.eclipse.ditto.base.model.signals.commands.exceptions.GatewayInternalErrorException;
import org.eclipse.ditto.base.model.signals.commands.exceptions.DittoInternalErrorException;
import org.eclipse.ditto.internal.utils.akka.logging.DittoLoggerFactory;
import org.eclipse.ditto.internal.utils.cluster.DistPubSubAccess;

Expand Down Expand Up @@ -101,7 +101,7 @@ private void unblockNamespace(final UnblockNamespace command) {
private Void handleError(final Throwable error, final Command<?> command, final ActorRef sender) {
log.error(error, "Failed to perform <{}>", command);
final var message = DittoRuntimeException.asDittoRuntimeException(error, t ->
GatewayInternalErrorException.newBuilder()
DittoInternalErrorException.newBuilder()
.message(error.getClass() + ": " + error.getMessage())
.dittoHeaders(command.getDittoHeaders())
.cause(t)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import org.eclipse.ditto.base.model.headers.WithDittoHeaders;
import org.eclipse.ditto.base.model.signals.commands.Command;
import org.eclipse.ditto.base.model.signals.commands.CommandResponse;
import org.eclipse.ditto.base.model.signals.commands.exceptions.GatewayInternalErrorException;
import org.eclipse.ditto.base.model.signals.commands.exceptions.DittoInternalErrorException;
import org.eclipse.ditto.internal.utils.akka.actors.AbstractActorWithStashWithTimers;
import org.eclipse.ditto.internal.utils.akka.logging.DittoDiagnosticLoggingAdapter;
import org.eclipse.ditto.internal.utils.akka.logging.DittoLoggerFactory;
Expand Down Expand Up @@ -261,7 +261,7 @@ private CompletionStage<Boolean> doEnforceCommand(final C command,
} else if (null != throwable) {
final DittoRuntimeException dittoRuntimeException =
DittoRuntimeException.asDittoRuntimeException(throwable, t ->
GatewayInternalErrorException.newBuilder()
DittoInternalErrorException.newBuilder()
.cause(t)
.dittoHeaders(command.getDittoHeaders())
.build()
Expand Down Expand Up @@ -311,8 +311,7 @@ private void filterResponse(final R commandResponse) {
} else if (null != throwable) {
final DittoRuntimeException dittoRuntimeException =
DittoRuntimeException.asDittoRuntimeException(throwable, t ->
// TODO TJ different exception than GatewayInternalErrorException
GatewayInternalErrorException.newBuilder()
DittoInternalErrorException.newBuilder()
.cause(t)
.dittoHeaders(commandResponse.getDittoHeaders())
.build()
Expand Down
Loading

0 comments on commit 3b27fba

Please sign in to comment.