filter(E message) {
*
* This method assumes that the given message has passed the filtering.
*
- * @see #post(Signal, StreamObserver) for the public API
+ * @see #post(Signal, StreamObserver) the public API for posting
*/
protected abstract void dispatch(E envelope);
/**
* Posts each of the given envelopes into the bus and notifies the given observer.
*
+ *
If {@link #dispatch(SignalEnvelope) dispatching} throws a {@link Mistake} it is rethrown.
+ * Other types of exceptions are logged and then rethrown.
+ *
+ *
We treat {@link Mistake}s differently and want to void much of console output
+ * for this special case of exceptions.
+ * Please see {@link io.spine.server.model.AbstractReceptor#invoke(Object, MessageEnvelope)}
+ * for more details on special treatment of {@link Mistake} during dispatching.
+ *
* @param envelopes
* the envelopes to post
* @param observer
@@ -370,6 +379,8 @@ private void doPost(Iterable envelopes, StreamObserver observer) {
onDispatchingStarted(signalId);
try {
dispatch(envelope);
+ } catch (Mistake m) {
+ throw m;
} catch (Throwable t) {
logger().atError().withCause(t).log(() -> format(
"Unable to dispatch `%s` with ID `%s`.",
diff --git a/server/src/main/java/io/spine/server/model/AbstractReceptor.java b/server/src/main/java/io/spine/server/model/AbstractReceptor.java
index 9af8d51f24..1eddd997a8 100644
--- a/server/src/main/java/io/spine/server/model/AbstractReceptor.java
+++ b/server/src/main/java/io/spine/server/model/AbstractReceptor.java
@@ -30,6 +30,7 @@
import com.google.errorprone.annotations.Immutable;
import com.google.errorprone.annotations.OverridingMethodsMustInvokeSuper;
import com.google.protobuf.Message;
+import io.spine.base.Mistake;
import io.spine.base.RejectionThrowable;
import io.spine.core.Signal;
import io.spine.server.dispatch.DispatchOutcome;
@@ -272,8 +273,8 @@ private static ImmutableSet> discoverAttributes(Method method) {
/**
* Feeds the given {@code envelope} to the given {@code target} and returns the outcome.
*
- * If the target method throws {@link java.lang.Error} dispatching terminates with
- * rethrowing the error.
+ *
If the target method throws {@link Mistake}, dispatching terminates with
+ * rethrowing it.
*
*
Other types of exceptions are converted to {@link io.spine.base.Error} and returned
* {@link DispatchOutcome.Builder#setError inside} the {@link DispatchOutcome}.
@@ -285,8 +286,8 @@ private static ImmutableSet> discoverAttributes(Method method) {
*/
@SuppressWarnings({
"ChainOfInstanceofChecks" /* We need to separate exceptions. */,
- "ThrowInsideCatchBlockWhichIgnoresCaughtException", "ProhibitedExceptionThrown"
- /* Rethrowing `Error`. See Javadoc. */
+ "ThrowInsideCatchBlockWhichIgnoresCaughtException",
+ /* Rethrowing `Mistake`. See Javadoc. */
})
@Override
public DispatchOutcome invoke(T target, E envelope) {
@@ -312,8 +313,8 @@ public DispatchOutcome invoke(T target, E envelope) {
} catch (InvocationTargetException e) {
var cause = e.getCause();
checkNotNull(cause);
- if (cause instanceof Error) {
- throw (Error) cause;
+ if (cause instanceof Mistake) {
+ throw (Mistake) cause;
} else if (cause instanceof RejectionThrowable) {
var success = asRejection(target, envelope, (RejectionThrowable) cause);
outcome.setSuccess(success);
diff --git a/server/src/test/kotlin/io/spine/server/model/AbstractReceptorSpec.kt b/server/src/test/kotlin/io/spine/server/model/AbstractReceptorSpec.kt
index c8138f7746..79aa6eb409 100644
--- a/server/src/test/kotlin/io/spine/server/model/AbstractReceptorSpec.kt
+++ b/server/src/test/kotlin/io/spine/server/model/AbstractReceptorSpec.kt
@@ -32,6 +32,7 @@ import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.spine.base.EventMessage
import io.spine.base.Identifier
+import io.spine.base.Mistake
import io.spine.core.Event
import io.spine.core.Subscribe
import io.spine.protobuf.AnyPacker
@@ -216,17 +217,17 @@ internal class AbstractReceptorSpec {
}
@Nested inner class
- `propagate instances of 'Error'` {
+ `propagate instances of 'Mistake'` {
- private val signature = SubscriberSignature();
+ private val signature = SubscriberSignature()
@Test
- fun `if a target throws 'java_lang_Error'`() {
- val receptor = signature.classify(ErrorThrowingHandler.method("throwingError"))
+ fun `if a target throws 'Mistake'`() {
+ val receptor = signature.classify(MistakenHandler.method("throwingMistake"))
receptor.shouldBePresent()
val envelope = envelope(projectCreated())
- assertThrows {
- receptor.get().invoke(ErrorThrowingHandler(), envelope)
+ assertThrows {
+ receptor.get().invoke(MistakenHandler(), envelope)
}
}
@@ -238,21 +239,24 @@ internal class AbstractReceptorSpec {
/**
* A subscriber which throws [java.lang.Error] and [kotlin.Error] in the receptors.
*/
-private class ErrorThrowingHandler : EventSubscriber {
+private class MistakenHandler : EventSubscriber {
companion object {
fun method(name: String): Method {
- return ModelTests.getMethod(ErrorThrowingHandler::class.java, name)
+ return ModelTests.getMethod(MistakenHandler::class.java, name)
}
}
@Subscribe
@Suppress("TooGenericExceptionThrown", "UNUSED_PARAMETER")
- fun throwingError(e: RefProjectCreated) {
- throw Error("Throwing `java.lang.Error`.")
+ fun throwingMistake(e: RefProjectCreated) {
+ throw StubMistake()
}
}
+@Suppress("serial") // No need for the tests.
+private class StubMistake: Mistake()
+
private fun envelope(eventMessage: EventMessage): EventEnvelope {
val factory = TestEventFactory.newInstance(AbstractReceptorSpec::class.java)
val event = factory.createEvent(eventMessage)
diff --git a/version.gradle.kts b/version.gradle.kts
index 5d592965f0..1fc30bad3a 100644
--- a/version.gradle.kts
+++ b/version.gradle.kts
@@ -29,4 +29,4 @@
*
* For versions of Spine-based dependencies, please see [io.spine.dependency.local.Spine].
*/
-val versionToPublish: String by extra("2.0.0-SNAPSHOT.190")
+val versionToPublish: String by extra("2.0.0-SNAPSHOT.191")