You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/04/06 08:19:16 UTC

[isis] branch master updated: ISIS-2993: introduces Try

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new b403c67169 ISIS-2993: introduces Try<T>
b403c67169 is described below

commit b403c671699b1212c1bf4dc3aa04245e08ba42e5
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Apr 6 10:19:08 2022 +0200

    ISIS-2993: introduces Try<T>
    
    - applib: replace occurrences of Result<T> with Try<T> in
---
 .../isis/applib/services/command/Command.java      |   4 +-
 .../services/command/CommandOutcomeHandler.java    |  10 +-
 .../services/iactnlayer/InteractionService.java    |  24 +-
 .../services/xactn/TransactionalProcessor.java     |  20 +-
 .../java/org/apache/isis/applib/util/JaxbUtil.java |  30 +--
 .../iactnlayer/{ResultTest.java => TryTest.java}   |  72 +++---
 .../org/apache/isis/commons/functional/Result.java |   1 +
 .../isis/commons/functional/ThrowingRunnable.java  |   4 +-
 .../org/apache/isis/commons/functional/Try.java    | 272 +++++++++++++++++++++
 ...ctionInvocationFacetForDomainEventAbstract.java |   8 +-
 ...tySetterOrClearFacetForDomainEventAbstract.java |   4 +-
 .../command/CommandExecutorServiceDefault.java     |   4 +-
 .../executor/MemberExecutorServiceDefault.java     |   4 +-
 .../transaction/TransactionServiceSpring.java      |   9 +-
 .../wrapper/WrapperFactoryDefault.java             |   4 +-
 .../commandlog/jdo/CommandSubscriberForJdo.java    |   8 +-
 .../commandlog/jdo/entities/CommandJdo.java        |   4 +-
 .../commandlog/jpa/entities/CommandJpa.java        |   4 +-
 .../jobcallables/ReplicateAndRunCommands.java      |  14 +-
 .../metamodel/facets/entity/JdoEntityFacet.java    |   8 +-
 ...xceptionTranslationTest_usingTransactional.java |   2 +-
 ...xceptionTranslationTest_usingTransactional.java |   2 +-
 .../isis/testdomain/RegressionTestAbstract.java    |   4 +-
 .../applib/fixturescripts/FixtureScripts.java      |   4 +-
 .../IsisRestfulObjectsInteractionFilter.java       |   2 +-
 25 files changed, 393 insertions(+), 129 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java b/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
index db6beccb69..640e57ca59 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
@@ -32,7 +32,7 @@ import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.control.AsyncControl;
-import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 
 import lombok.Getter;
@@ -327,7 +327,7 @@ public class Command implements HasInteractionId, HasUsername, HasCommandDto {
          * <b>NOT API</b>: intended to be called only by the framework.
          */
         @Override
-        public void setResult(final Result<Bookmark> resultBookmark) {
+        public void setResult(final Try<Bookmark> resultBookmark) {
             Command.this.result = resultBookmark.getValue().orElse(null);
             Command.this.exception = resultBookmark.getFailure().orElse(null);
         }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandOutcomeHandler.java b/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandOutcomeHandler.java
index 84836e83f2..0af03a07f8 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandOutcomeHandler.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandOutcomeHandler.java
@@ -21,7 +21,7 @@ package org.apache.isis.applib.services.command;
 import java.sql.Timestamp;
 
 import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 
 /**
  * Used by {@link CommandExecutorService}, to update a {@link Command} after it has been executed.
@@ -32,9 +32,9 @@ public interface CommandOutcomeHandler {
 
     CommandOutcomeHandler NULL = new CommandOutcomeHandler() {
         @Override public Timestamp getStartedAt() { return null; }
-        @Override public void setStartedAt(Timestamp startedAt) { }
-        @Override public void setCompletedAt(Timestamp completedAt) { }
-        @Override public void setResult(Result<Bookmark> resultBookmark) { }
+        @Override public void setStartedAt(final Timestamp startedAt) { }
+        @Override public void setCompletedAt(final Timestamp completedAt) { }
+        @Override public void setResult(final Try<Bookmark> resultBookmark) { }
     };
 
     /**
@@ -66,6 +66,6 @@ public interface CommandOutcomeHandler {
     /**
      * Sets the result of the execute, represented as a {@link Bookmark}, on the underlying {@link Command} (or persistent equivalent).
      */
-    void setResult(Result<Bookmark> resultBookmark);
+    void setResult(Try<Bookmark> resultBookmark);
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionService.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionService.java
index 51b9a1b7f0..f52606599c 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionService.java
@@ -20,8 +20,8 @@ package org.apache.isis.applib.services.iactnlayer;
 
 import java.util.concurrent.Callable;
 
-import org.apache.isis.commons.functional.Result;
 import org.apache.isis.commons.functional.ThrowingRunnable;
+import org.apache.isis.commons.functional.Try;
 
 import lombok.NonNull;
 
@@ -140,24 +140,24 @@ public interface InteractionService extends InteractionLayerTracker {
      */
     void runAnonymous(@NonNull ThrowingRunnable runnable);
 
-    // -- RESULT SUPPORT
+    // -- TRY SUPPORT
 
     /**
      * Variant of {@link #call(InteractionContext, Callable)} that wraps the return value
-     * with a {@link Result}, also catching any exception, that might have occurred.
+     * with a {@link Try}, also catching any exception, that might have occurred.
      */
-    default <R> Result<R> callAndCatch(
+    default <R> Try<R> callAndCatch(
             final @NonNull InteractionContext interactionContext,
             final @NonNull Callable<R> callable) {
-        return Result.of(()->call(interactionContext, callable));
+        return Try.call(()->call(interactionContext, callable));
     }
 
     /**
      * Variant of {@link #run(InteractionContext, ThrowingRunnable)} that returns
-     * a {@link Result} of {@code Result<Void>},
+     * a {@link Try} of {@code Result<Void>},
      * also catching any exception, that might have occurred.
      */
-    default Result<Void> runAndCatch(
+    default Try<Void> runAndCatch(
             final @NonNull InteractionContext interactionContext,
             final @NonNull ThrowingRunnable runnable){
         return callAndCatch(interactionContext, ThrowingRunnable.toCallable(runnable));
@@ -165,19 +165,19 @@ public interface InteractionService extends InteractionLayerTracker {
 
     /**
      * Variant of {@link #callAnonymous(Callable)} that wraps the return value
-     * with a {@link Result}, also catching any exception, that might have occurred.
+     * with a {@link Try}, also catching any exception, that might have occurred.
      */
-    default <R> Result<R> callAnonymousAndCatch(
+    default <R> Try<R> callAnonymousAndCatch(
             final @NonNull Callable<R> callable) {
-        return Result.of(()->callAnonymous(callable));
+        return Try.call(()->callAnonymous(callable));
     }
 
     /**
      * Variant of {@link #runAnonymous(ThrowingRunnable)} that returns
-     * a {@link Result} of {@code Result<Void>},
+     * a {@link Try} of {@code Try<Void>},
      * also catching any exception, that might have occurred.
      */
-    default Result<Void> runAnonymousAndCatch(
+    default Try<Void> runAnonymousAndCatch(
             final @NonNull ThrowingRunnable runnable) {
         return callAnonymousAndCatch(ThrowingRunnable.toCallable(runnable));
     }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
index 0f1a16b68e..e3275bcfce 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
@@ -24,8 +24,8 @@ import org.springframework.transaction.TransactionDefinition;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.support.DefaultTransactionDefinition;
 
-import org.apache.isis.commons.functional.Result;
 import org.apache.isis.commons.functional.ThrowingRunnable;
+import org.apache.isis.commons.functional.Try;
 
 import lombok.val;
 
@@ -44,15 +44,15 @@ public interface TransactionalProcessor {
     /**
      * Runs given {@code callable} with a transactional boundary, where the detailed transactional behavior
      * is governed by given {@link TransactionDefinition} {@code def}.
-     * @return {@link Result} of calling given {@code callable}
+     * @return {@link Try} of calling given {@code callable}
      */
-    <T> Result<T> callTransactional(TransactionDefinition def, Callable<T> callable);
+    <T> Try<T> callTransactional(TransactionDefinition def, Callable<T> callable);
 
     /**
      * Runs given {@code runnable} with a transactional boundary, where the detailed transactional behavior
      * is governed by given {@link TransactionDefinition} {@code def}.
      */
-    default Result<Void> runTransactional(final TransactionDefinition def, final ThrowingRunnable runnable) {
+    default Try<Void> runTransactional(final TransactionDefinition def, final ThrowingRunnable runnable) {
         return callTransactional(def, ThrowingRunnable.toCallable(runnable));
     }
 
@@ -63,9 +63,9 @@ public interface TransactionalProcessor {
      * is governed by given {@link Propagation} {@code propagation}.
      * <p>
      * More fine grained control is given via {@link #callTransactional(TransactionDefinition, Callable)}
-     * @return {@link Result} of calling given {@code callable}
+     * @return {@link Try} of calling given {@code callable}
      */
-    default <T> Result<T> callTransactional(final Propagation propagation, final Callable<T> callable) {
+    default <T> Try<T> callTransactional(final Propagation propagation, final Callable<T> callable) {
         val def = new DefaultTransactionDefinition();
         def.setPropagationBehavior(propagation.value());
         return callTransactional(def, callable);
@@ -78,7 +78,7 @@ public interface TransactionalProcessor {
      * More fine grained control is given via
      * {@link #runTransactional(TransactionDefinition, ThrowingRunnable)}
      */
-    default Result<Void> runTransactional(final Propagation propagation, final ThrowingRunnable runnable) {
+    default Try<Void> runTransactional(final Propagation propagation, final ThrowingRunnable runnable) {
         return callTransactional(propagation, ThrowingRunnable.toCallable(runnable));
     }
 
@@ -92,9 +92,9 @@ public interface TransactionalProcessor {
      * In other words, support a current transaction, create a new one if none exists.
      * @param <T>
      * @param callable
-     * @return {@link Result} of calling given {@code callable}
+     * @return {@link Try} of calling given {@code callable}
      */
-    default <T> Result<T> callWithinCurrentTransactionElseCreateNew(final Callable<T> callable) {
+    default <T> Try<T> callWithinCurrentTransactionElseCreateNew(final Callable<T> callable) {
         val def = new DefaultTransactionDefinition();
         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
         return callTransactional(def, callable);
@@ -106,7 +106,7 @@ public interface TransactionalProcessor {
      *
      * @param runnable
      */
-    default Result<Void> runWithinCurrentTransactionElseCreateNew(final ThrowingRunnable runnable) {
+    default Try<Void> runWithinCurrentTransactionElseCreateNew(final ThrowingRunnable runnable) {
         return callWithinCurrentTransactionElseCreateNew(ThrowingRunnable.toCallable(runnable));
     }
 
diff --git a/api/applib/src/main/java/org/apache/isis/applib/util/JaxbUtil.java b/api/applib/src/main/java/org/apache/isis/applib/util/JaxbUtil.java
index 7f5da16df6..5e5c4d37bc 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/util/JaxbUtil.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/util/JaxbUtil.java
@@ -27,7 +27,7 @@ import java.io.Writer;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 
-import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 import org.apache.isis.commons.internal.resources._Resources;
 import org.apache.isis.commons.internal.resources._Xml;
 import org.apache.isis.commons.internal.resources._Xml.ReadOptions;
@@ -55,17 +55,17 @@ public class JaxbUtil {
     private static <T> T _fromXml(
             final @NonNull Reader reader,
             final @NonNull Class<T> dtoClass) {
-        
+
         return _Xml._readXml(dtoClass, reader, ReadOptions.builder()
                 .useContextCache(true)
                 .build());
     }
-    
-    public static <T> Result<T> fromXml(
+
+    public static <T> Try<T> fromXml(
             final @NonNull Reader reader,
             final @NonNull Class<T> dtoClass) {
-        
-        return Result.of(()->_fromXml(reader, dtoClass));
+
+        return Try.call(()->_fromXml(reader, dtoClass));
     }
 
     private static <T> T _fromXml(
@@ -76,36 +76,36 @@ public class JaxbUtil {
         val xmlString = _Resources.loadAsStringUtf8(contextClass, resourceName);
         return _fromXml(new StringReader(xmlString), dtoClass);
     }
-    
-    public static <T> Result<T> fromXml(
+
+    public static <T> Try<T> fromXml(
             final @NonNull Class<?> contextClass,
             final @NonNull String resourceName,
             final @NonNull Class<T> dtoClass) throws IOException {
 
-        return Result.of(()->_fromXml(contextClass, resourceName, dtoClass));
+        return Try.call(()->_fromXml(contextClass, resourceName, dtoClass));
     }
 
     // -- WRITE
 
-    public static Result<String> toXml(final @NonNull Object dto) {
-        return Result.of(()->{
+    public static Try<String> toXml(final @NonNull Object dto) {
+        return Try.call(()->{
             val caw = new CharArrayWriter();
             toXml(dto, caw);
-            return caw.toString();    
+            return caw.toString();
         });
     }
 
     public static <T> void toXml(
-            final @NonNull T dto, 
+            final @NonNull T dto,
             final @NonNull Writer writer) throws JAXBException {
         _Xml.writeXml(dto, writer, WriteOptions.builder()
                 .useContextCache(true)
                 .formattedOutput(true)
                 .build());
     }
-    
+
     // -- CACHING
-    
+
     public static JAXBContext jaxbContextFor(final @NonNull Class<?> dtoClass) {
         val useCache = true;
         return _Xml.jaxbContextFor(dtoClass, useCache);
diff --git a/api/applib/src/test/java/org/apache/isis/applib/services/iactnlayer/ResultTest.java b/api/applib/src/test/java/org/apache/isis/applib/services/iactnlayer/TryTest.java
similarity index 62%
rename from api/applib/src/test/java/org/apache/isis/applib/services/iactnlayer/ResultTest.java
rename to api/applib/src/test/java/org/apache/isis/applib/services/iactnlayer/TryTest.java
index 2750ef4546..bf454bd1a5 100644
--- a/api/applib/src/test/java/org/apache/isis/applib/services/iactnlayer/ResultTest.java
+++ b/api/applib/src/test/java/org/apache/isis/applib/services/iactnlayer/TryTest.java
@@ -29,12 +29,12 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
-import org.apache.isis.commons.functional.Result;
 import org.apache.isis.commons.functional.ThrowingRunnable;
+import org.apache.isis.commons.functional.Try;
 
 import lombok.val;
 
-class ResultTest {
+class TryTest {
 
     // -- TEST DUMMIES
 
@@ -72,54 +72,51 @@ class ResultTest {
     @Test
     void hello_happy_case() {
 
-        val result = Result.<String>of(this::hello_happy);
+        val result = Try.<String>call(this::hello_happy);
         assertTrue(result.isSuccess());
         assertFalse(result.isFailure());
-        assertEquals("hello", result.presentElse(""));
+        assertEquals("hello", result.getValue().orElse(""));
         assertEquals("hello", result.getValue().orElse(null));
-        assertEquals("hello", result.presentElseFail());
+        assertEquals("hello", result.ifAbsentFail().getValue().get());
 
         // non-evaluated code-path
-        result.presentElseGet(()->fail("unexpected code reach"));
+        result.getValue().orElseGet(()->fail("unexpected code reach"));
 
-        // default value is not allowed to be null
-        assertThrows(NullPointerException.class, ()->result.presentElse(null));
-
-        val mandatory = result.mapSuccessWithEmptyValueToNoSuchElement();
+        val mandatory = result.mapEmptyToFailure();
         assertTrue(mandatory.isSuccess());
-        assertEquals("hello", mandatory.presentElse(""));
+        assertEquals("hello", mandatory.getValue().orElse(""));
 
     }
 
     @Test
     void hello_nullable_case() {
 
-        val result = Result.<String>of(this::hello_nullable);
+        val result = Try.<String>call(this::hello_nullable);
         assertTrue(result.isSuccess());
         assertFalse(result.isFailure());
         assertEquals("no value", result.getValue().orElse("no value"));
-        assertThrows(NoSuchElementException.class, ()->result.presentElseFail());
-        assertEquals(Optional.empty(), result.optionalElseFail());
+        assertThrows(NoSuchElementException.class, ()->result.ifAbsentFail());
+        assertEquals(Optional.empty(), result.ifFailureFail().getValue());
 
-        val mandatory = result.mapSuccessWithEmptyValueToNoSuchElement();
+        val mandatory = result.mapEmptyToFailure();
         assertTrue(mandatory.isFailure());
-        assertThrows(NoSuchElementException.class, ()->mandatory.optionalElseFail());
+        assertThrows(NoSuchElementException.class, ()->mandatory.ifFailureFail());
 
     }
 
     @Test
     void hello_throwing_uncatched_case() {
 
-        val result = Result.<String>of(this::hello_throwing_uncatched);
+        val result = Try.<String>call(this::hello_throwing_uncatched);
         assertFalse(result.isSuccess());
         assertTrue(result.isFailure());
         assertEquals("hello failed", result.getFailure().get().getMessage());
-        assertEquals("it failed", result.presentElse("it failed"));
-        assertEquals("it failed", result.presentElseGet(()->"it failed"));
-        assertThrows(RuntimeException.class, ()->result.presentElseFail());
+        assertEquals("it failed", result.getValue().orElse("it failed"));
+        assertEquals("it failed", result.getValue().orElseGet(()->"it failed"));
+        assertThrows(RuntimeException.class, ()->result.ifAbsentFail());
         assertEquals(Optional.empty(), result.getValue());
 
-        val mandatory = result.mapSuccessWithEmptyValueToNoSuchElement();
+        val mandatory = result.mapEmptyToFailure();
         assertTrue(mandatory.isFailure());
 
     }
@@ -127,16 +124,16 @@ class ResultTest {
     @Test
     void hello_throwing_catched_case() {
 
-        val result = Result.<String>of(this::hello_throwing_catched);
+        val result = Try.<String>call(this::hello_throwing_catched);
         assertFalse(result.isSuccess());
         assertTrue(result.isFailure());
         assertEquals("hello failed", result.getFailure().get().getMessage());
-        assertEquals("it failed", result.presentElse("it failed"));
-        assertEquals("it failed", result.presentElseGet(()->"it failed"));
-        assertThrows(Exception.class, ()->result.presentElseFail());
+        assertEquals("it failed", result.getValue().orElse("it failed"));
+        assertEquals("it failed", result.getValue().orElseGet(()->"it failed"));
+        assertThrows(Exception.class, ()->result.ifAbsentFail());
         assertEquals(Optional.empty(), result.getValue());
 
-        val mandatory = result.mapSuccessWithEmptyValueToNoSuchElement();
+        val mandatory = result.mapEmptyToFailure();
         assertTrue(mandatory.isFailure());
 
     }
@@ -149,14 +146,9 @@ class ResultTest {
         assertFalse(result.isFailure());
         assertEquals(null, result.getValue().orElse(null));
 
-        assertThrows(NoSuchElementException.class, ()->result.presentElseFail());
-
-        // default value is not allowed to be null
-        assertThrows(NullPointerException.class, ()->result.presentElse(null));
-
+        assertThrows(NoSuchElementException.class, ()->result.ifAbsentFail());
     }
 
-
     @Test
     void void_throwing_uncatched_case() {
 
@@ -165,13 +157,11 @@ class ResultTest {
         assertTrue(result.isFailure());
         assertEquals("void failed", result.getFailure().get().getMessage());
 
-        // default value is not allowed to be null
-        assertThrows(NullPointerException.class, ()->result.presentElse(null));
-        assertThrows(NoSuchElementException.class, ()->result.presentElseGet(()->null));
-        assertThrows(Exception.class, ()->result.presentElseFail());
+        assertThrows(RuntimeException.class, ()->result.ifFailureFail()); // throw contained exception
+        assertThrows(NoSuchElementException.class, ()->result.ifAbsentFail()); // throw NoSuchElementException always
         assertEquals(Optional.empty(), result.getValue());
 
-        val mandatory = result.mapSuccessWithEmptyValueToNoSuchElement();
+        val mandatory = result.mapEmptyToFailure();
         assertTrue(mandatory.isFailure());
     }
 
@@ -183,13 +173,11 @@ class ResultTest {
         assertTrue(result.isFailure());
         assertEquals("void failed", result.getFailure().get().getMessage());
 
-        // default value is not allowed to be null
-        assertThrows(NullPointerException.class, ()->result.presentElse(null));
-        assertThrows(NoSuchElementException.class, ()->result.presentElseGet(()->null));
-        assertThrows(Exception.class, ()->result.presentElseFail());
+        assertThrows(Exception.class, ()->result.ifFailureFail()); // throw contained exception
+        assertThrows(NoSuchElementException.class, ()->result.ifAbsentFail()); // throw NoSuchElementException always
         assertEquals(Optional.empty(), result.getValue());
 
-        val mandatory = result.mapSuccessWithEmptyValueToNoSuchElement();
+        val mandatory = result.mapEmptyToFailure();
         assertTrue(mandatory.isFailure());
     }
 
diff --git a/commons/src/main/java/org/apache/isis/commons/functional/Result.java b/commons/src/main/java/org/apache/isis/commons/functional/Result.java
index 82f3731742..5177f2fe58 100644
--- a/commons/src/main/java/org/apache/isis/commons/functional/Result.java
+++ b/commons/src/main/java/org/apache/isis/commons/functional/Result.java
@@ -43,6 +43,7 @@ import lombok.val;
  *
  * @since 2.0 {@index}
  */
+@Deprecated(forRemoval = true, since = "2.0.0-M7")
 @RequiredArgsConstructor(access=AccessLevel.PRIVATE, staticName="of")
 @ToString @EqualsAndHashCode
 public final class Result<L> {
diff --git a/commons/src/main/java/org/apache/isis/commons/functional/ThrowingRunnable.java b/commons/src/main/java/org/apache/isis/commons/functional/ThrowingRunnable.java
index 9aad51cea9..0045572e63 100644
--- a/commons/src/main/java/org/apache/isis/commons/functional/ThrowingRunnable.java
+++ b/commons/src/main/java/org/apache/isis/commons/functional/ThrowingRunnable.java
@@ -44,7 +44,7 @@ public interface ThrowingRunnable {
         };
     }
 
-    static Result<Void> resultOf(final @NonNull ThrowingRunnable runnable) {
-        return Result.of(toCallable(runnable));
+    static Try<Void> resultOf(final @NonNull ThrowingRunnable runnable) {
+        return Try.run(runnable);
     }
 }
diff --git a/commons/src/main/java/org/apache/isis/commons/functional/Try.java b/commons/src/main/java/org/apache/isis/commons/functional/Try.java
new file mode 100644
index 0000000000..1f373f32b1
--- /dev/null
+++ b/commons/src/main/java/org/apache/isis/commons/functional/Try.java
@@ -0,0 +1,272 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.isis.commons.functional;
+
+import java.util.NoSuchElementException;
+import java.util.Optional;
+import java.util.concurrent.Callable;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import org.springframework.lang.Nullable;
+
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+
+/**
+ * The {@link Try} type represents a value of one of two possible types (a disjoint union)
+ * of {@link Success} or {@link Failure}.
+ * <p>
+ * Factory methods {@link Try#success(Object)} and {@link Try#failure(Throwable)}
+ * correspond to the two possible values.
+ *
+ * @since 2.0 {@index}
+ */
+public interface Try<T> {
+
+    // -- FACTORIES
+
+    public static <T> Try<T> call(final @NonNull Callable<T> callable) {
+        try {
+            return success(callable.call());
+        } catch (Throwable e) {
+            return failure(e);
+        }
+    }
+
+    public static Try<Void> run(final @NonNull ThrowingRunnable runnable) {
+        try {
+            runnable.run();
+            return success(null);
+        } catch (Throwable e) {
+            return failure(e);
+        }
+    }
+
+    public static <T> Success<T> success(final @Nullable T value) {
+        return new Success<>(value);
+    }
+
+    public static <T> Failure<T> failure(final @NonNull Throwable throwable) {
+        return new Failure<T>(throwable);
+    }
+
+    // -- PREDICATES
+
+    boolean isSuccess();
+    boolean isFailure();
+
+    // -- ACCESSORS
+
+    /**
+     * Optionally returns the contained {@code value} based on presence,
+     * this is, if its a {@link Success} and the value is not {@code null}.
+     */
+    Optional<T> getValue();
+    /**
+     * Optionally returns the contained {@code failure} based on presence,
+     * this is, if its a {@link Failure}.
+     */
+    Optional<Throwable> getFailure();
+
+    // -- PEEKING
+
+    /**
+     * Peeks into the {@code value} if its a {@link Success}.
+     */
+    Try<T> ifSuccess(final @NonNull Consumer<Optional<T>> valueConsumer);
+    /**
+     * Peeks into the {@code failure} if its a {@link Failure}.
+     */
+    Try<T> ifFailure(final @NonNull Consumer<Throwable> exceptionConsumer);
+
+    // -- FAIL EARLY
+
+    /** Throws the contained failure if any. */
+    Try<T> ifFailureFail();
+    /** Throws {@link NoSuchElementException} if {@code value} is {@code null}. */
+    Try<T> ifAbsentFail();
+
+    // -- MAPPING
+
+    /**
+     * Maps this {@link Try} to another if its a {@link Success}.
+     * Otherwise if its a {@link Failure} acts as identity operator.
+     */
+    <R> Try<R> mapSuccess(final @NonNull Function<T, R> successMapper);
+    /**
+     * Maps this {@link Try} to another if its a {@link Failure}.
+     * Otherwise if its a {@link Success} acts as identity operator.
+     */
+    Try<T> mapFailure(final @NonNull UnaryOperator<Throwable> failureMapper);
+    /**
+     * Maps this {@link Try} to {@link Failure} if its a {@link Success} with an empty {@code value}.
+     * Otherwise acts as identity operator.
+     */
+    Try<T> mapEmptyToFailure();
+
+    // -- CONCATENATION
+
+    /**
+     * If its a {@link Success}, maps it to another based on given {@link Callable}.
+     * Otherwise if its a {@link Failure} acts as identity operator.
+     */
+    <R> Try<R> thenCall(final @NonNull Callable<R> callable);
+    /**
+     * If its a {@link Success}, maps it to another based on given {@link ThrowingRunnable}.
+     * Otherwise if its a {@link Failure} acts as identity operator.
+     */
+    Try<Void> thenRun(final @NonNull ThrowingRunnable runnable);
+
+    // -- SUCCESS
+
+    @lombok.Value
+    @RequiredArgsConstructor
+    final class Success<T> implements Try<T> {
+
+        private final @Nullable T value;
+
+        @Override public boolean isSuccess() { return true; }
+        @Override public boolean isFailure() { return false; }
+
+        @Override public Optional<T> getValue() { return Optional.ofNullable(value); }
+        @Override public Optional<Throwable> getFailure() { return Optional.empty(); }
+
+        @Override
+        public Success<T> ifSuccess(final @NonNull Consumer<Optional<T>> valueConsumer) {
+            valueConsumer.accept(getValue());
+            return this;
+        }
+
+        @Override
+        public Success<T> ifFailure(final @NonNull Consumer<Throwable> exceptionConsumer) {
+            return this;
+        }
+
+        @Override
+        public Success<T> ifFailureFail() {
+            return this;
+        }
+
+        @Override
+        public Success<T> ifAbsentFail() {
+            if(value==null) throw _Exceptions.noSuchElement();
+            return this;
+        }
+
+        @Override
+        public <R> Try<R> mapSuccess(final @NonNull Function<T, R> successMapper){
+            return Try.call(()->successMapper.apply(value));
+        }
+
+        @Override
+        public Success<T> mapFailure(final @NonNull UnaryOperator<Throwable> failureMapper){
+            return this;
+        }
+
+        @Override
+        public Try<T> mapEmptyToFailure() {
+            return value!=null
+                    ? this
+                    : Try.failure(_Exceptions.noSuchElement());
+        }
+
+        @Override
+        public <R> Try<R> thenCall(final @NonNull Callable<R> callable) {
+            return Try.call(callable);
+        }
+
+        @Override
+        public Try<Void> thenRun(final @NonNull ThrowingRunnable runnable) {
+            return Try.run(runnable);
+        }
+
+    }
+
+    // -- FAILURE
+
+    @lombok.Value
+    @RequiredArgsConstructor
+    final class Failure<T> implements Try<T> {
+
+        private final @NonNull Throwable throwable;
+
+        @Override public boolean isSuccess() { return false; }
+        @Override public boolean isFailure() { return true; }
+
+        @Override public Optional<T> getValue() { return Optional.empty(); }
+        @Override public Optional<Throwable> getFailure() { return Optional.of(throwable); }
+
+        @Override
+        public Failure<T> ifSuccess(final @NonNull Consumer<Optional<T>> valueConsumer) {
+            return this;
+        }
+
+        @Override
+        public Failure<T> ifFailure(final @NonNull Consumer<Throwable> exceptionConsumer) {
+            exceptionConsumer.accept(throwable);
+            return this;
+        }
+
+        @Override @SneakyThrows
+        public Failure<T> ifFailureFail() {
+            throw throwable;
+        }
+
+        @Override @SneakyThrows
+        public Failure<T> ifAbsentFail() {
+            throw _Exceptions.noSuchElement();
+        }
+
+        @Override
+        public <R> Failure<R> mapSuccess(final @NonNull Function<T, R> successMapper){
+            return new Failure<>(throwable);
+        }
+
+        @Override
+        public Failure<T> mapFailure(final @NonNull UnaryOperator<Throwable> failureMapper){
+            try {
+                return new Failure<>(failureMapper.apply(throwable));
+            } catch (Throwable e) {
+                return failure(e);
+            }
+        }
+
+        @Override
+        public Try<T> mapEmptyToFailure() {
+            return this;
+        }
+
+        @Override
+        public <R> Failure<R> thenCall(final @NonNull Callable<R> callable) {
+            return new Failure<>(throwable);
+        }
+
+        @Override
+        public Try<Void> thenRun(final @NonNull ThrowingRunnable runnable) {
+            return new Failure<>(throwable);
+        }
+
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index 6911527d34..921372036a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -30,7 +30,7 @@ import org.apache.isis.applib.services.iactn.ActionInvocation;
 import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.commons.internal.collections._Arrays;
 import org.apache.isis.core.metamodel.commons.CanonicalInvoker;
@@ -93,7 +93,7 @@ implements ImperativeFacet {
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         val executionResult = interactionInitiatedBy.isPassThrough()
-                ? Result.of(()->
+                ? Try.call(()->
                     doInvoke(owningAction, head, argumentAdapters, interactionInitiatedBy))
                 : getTransactionService().callWithinCurrentTransactionElseCreateNew(()->
                     doInvoke(owningAction, head, argumentAdapters, interactionInitiatedBy));
@@ -101,8 +101,8 @@ implements ImperativeFacet {
         //PersistableTypeGuard.instate(executionResult);
 
         return executionResult
-                .optionalElseFail()
-                .orElse(null);
+                .ifFailureFail()
+                .getValue().orElse(null);
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
index 2443613c36..8afc15df91 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
@@ -164,8 +164,8 @@ implements
                             InteractionHead.regular(targetAdapter),
                             newValueAdapter,
                             interactionInitiatedBy))
-                .optionalElseFail()
-                .orElse(null);
+                .ifFailureFail()
+                .getValue().orElse(null);
         }
 
     @RequiredArgsConstructor
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
index 4e279e0247..a932c328ea 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
@@ -47,7 +47,7 @@ import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.functional.IndexedFunction;
-import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -252,7 +252,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
 
     private Bookmark handleOutcomeAndSetCompletedAt(
             final CommandOutcomeHandler outcomeHandler,
-            final Result<Bookmark> result) {
+            final Try<Bookmark> result) {
 
 
         //
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
index c6d8a87949..e4e4d2e0be 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
@@ -39,7 +39,7 @@ import org.apache.isis.applib.services.iactnlayer.InteractionLayerTracker;
 import org.apache.isis.applib.services.metrics.MetricsService;
 import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -279,7 +279,7 @@ implements MemberExecutorService {
         if(entityState.isAttached()) {
             resultAdapter.getBookmark()
             .ifPresent(bookmark->
-                command.updater().setResult(Result.success(bookmark))
+                command.updater().setResult(Try.success(bookmark))
             );
         } else {
             if(entityState.isPersistable()) {
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
index 11b14a4d35..28f477f1be 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
@@ -46,6 +46,7 @@ import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.applib.services.xactn.TransactionState;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.interaction.scope.TransactionBoundaryAware;
@@ -95,17 +96,17 @@ implements
     // -- SPRING INTEGRATION
 
     @Override
-    public <T> Result<T> callTransactional(final TransactionDefinition def, final Callable<T> callable) {
+    public <T> Try<T> callTransactional(final TransactionDefinition def, final Callable<T> callable) {
 
         val txManager = transactionManagerForElseFail(def); // always throws if configuration is wrong
 
-        Result<T> result = null;
+        Try<T> result = null;
 
         try {
 
             val tx = txManager.getTransaction(def);
 
-            result = Result.of(callable)
+            result = Try.call(callable)
                     .mapFailure(ex->translateExceptionIfPossible(ex, txManager));
 
             if(result.isFailure()) {
@@ -124,7 +125,7 @@ implements
                     ? result
 
                     // return the failure we just catched
-                    : Result.failure(translateExceptionIfPossible(ex, txManager));
+                    : Try.failure(translateExceptionIfPossible(ex, txManager));
 
         }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
index cb0712d746..d49125f879 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
@@ -600,8 +600,8 @@ public class WrapperFactoryDefault implements WrapperFactory {
 
         private R updateDomainObjectHonoringTransactionalPropagation() {
             return transactionService.callTransactional(propagation, this::updateDomainObject)
-                    .optionalElseFail()
-                    .orElse(null);
+                    .ifFailureFail()
+                    .getValue().orElse(null);
         }
 
         private R updateDomainObject() {
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/CommandSubscriberForJdo.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/CommandSubscriberForJdo.java
index 599499f7c3..e369d741f9 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/CommandSubscriberForJdo.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/CommandSubscriberForJdo.java
@@ -49,7 +49,7 @@ public class CommandSubscriberForJdo implements CommandSubscriber {
     @Inject final CommandJdoRepository commandJdoRepository;
 
     @Override
-    public void onCompleted(Command command) {
+    public void onCompleted(final Command command) {
 
         if(!command.isSystemStateChanged()) {
             return;
@@ -62,8 +62,10 @@ public class CommandSubscriberForJdo implements CommandSubscriber {
                 // this isn't expected to happen ... we just log the fact if it does
                 val existingCommandDto = existingCommandJdoIfAny.get().getCommandDto();
 
-                val existingCommandDtoXml = JaxbUtil.toXml(existingCommandDto).presentElse("Dto to Xml failure");
-                val commandDtoXml = JaxbUtil.toXml(command.getCommandDto()).presentElse("Dto to Xml failure");
+                val existingCommandDtoXml = JaxbUtil.toXml(existingCommandDto)
+                        .getValue().orElse("Dto to Xml failure");
+                val commandDtoXml = JaxbUtil.toXml(command.getCommandDto())
+                        .getValue().orElse("Dto to Xml failure");
 
                 log.debug("existing: \n{}", existingCommandDtoXml);
                 log.debug("proposed: \n{}", commandDtoXml);
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.java
index 08bbc73d15..8ce7d7bf5e 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.java
@@ -51,7 +51,7 @@ import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
 import org.apache.isis.applib.services.tablecol.TableColumnOrderForCollectionTypeAbstract;
 import org.apache.isis.applib.types.MemberIdentifierType;
 import org.apache.isis.applib.util.TitleBuffer;
-import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
@@ -613,7 +613,7 @@ implements
             }
 
             @Override
-            public void setResult(final Result<Bookmark> resultBookmark) {
+            public void setResult(final Try<Bookmark> resultBookmark) {
                 CommandJdo.this.setResult(resultBookmark.getValue().orElse(null));
                 CommandJdo.this.setException(resultBookmark.getFailure().orElse(null));
             }
diff --git a/extensions/core/command-log/jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/entities/CommandJpa.java b/extensions/core/command-log/jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/entities/CommandJpa.java
index 973060a13f..a2dbcbdba7 100644
--- a/extensions/core/command-log/jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/entities/CommandJpa.java
+++ b/extensions/core/command-log/jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/entities/CommandJpa.java
@@ -50,7 +50,7 @@ import org.apache.isis.applib.services.command.CommandOutcomeHandler;
 import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
 import org.apache.isis.applib.services.tablecol.TableColumnOrderForCollectionTypeAbstract;
 import org.apache.isis.applib.util.TitleBuffer;
-import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.functional.Try;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
@@ -598,7 +598,7 @@ implements
             }
 
             @Override
-            public void setResult(final Result<Bookmark> resultBookmark) {
+            public void setResult(final Try<Bookmark> resultBookmark) {
                 CommandJpa.this.setResult(resultBookmark.getValue().orElse(null));
                 CommandJpa.this.setException(resultBookmark.getFailure().orElse(null));
             }
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
index 2d368076e1..984ff12a8e 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
@@ -112,8 +112,8 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
                         .map(dto ->
                                 transactionService.callWithinCurrentTransactionElseCreateNew(
                                     () -> commandModelRepository.saveForReplay(dto))
-                                .optionalElseFail()
-                                .orElse(null)
+                                .ifFailureFail()
+                                .getValue().orElse(null)
                         )
                         .collect(Collectors.toList());
 
@@ -131,7 +131,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
      * @param commandsToReplay
      * @apiNote could return, whether there was a command to process (and so continue)
      */
-    private void replay(List<? extends CommandModel> commandsToReplay) {
+    private void replay(final List<? extends CommandModel> commandsToReplay) {
 
         commandsToReplay.forEach(commandModel -> {
 
@@ -155,8 +155,8 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
             val childCommands =
                     transactionService.callWithinCurrentTransactionElseCreateNew(
                             () -> commandModelRepository.findByParent(parent))
-                    .optionalElseFail()
-                    .orElse(Collections.emptyList());
+                    .ifFailureFail()
+                    .getValue().orElse(Collections.emptyList());
             for (val childCommand : childCommands) {
                 val childReplayState = executeCommandInTranAndAnalyse(childCommand);
                 if(childReplayState.isFailed()) {
@@ -189,8 +189,8 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
         return controller
                 .map( control -> transactionService
                         .callWithinCurrentTransactionElseCreateNew(control::getState)
-                        .optionalElseFail()
-                        .orElse(null))
+                        .ifFailureFail()
+                        .getValue().orElse(null))
                 .map(state -> state == ReplayCommandExecutionController.State.RUNNING)
             // if no controller implementation provided, then just continue
             .orElse(true);
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
index c4987aec05..923fe45fea 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
@@ -270,7 +270,7 @@ implements EntityFacet {
 
         getTransactionalProcessor()
         .runWithinCurrentTransactionElseCreateNew(()->pm.makePersistent(pojo))
-        .optionalElseFail();
+        .ifFailureFail();
 
         //TODO integrate with entity change tracking
     }
@@ -292,7 +292,7 @@ implements EntityFacet {
 
         getTransactionalProcessor()
         .runWithinCurrentTransactionElseCreateNew(()->pm.deletePersistent(pojo))
-        .optionalElseFail();
+        .ifFailureFail();
 
         //TODO integrate with entity change tracking
     }
@@ -312,7 +312,7 @@ implements EntityFacet {
 
         getTransactionalProcessor()
         .runWithinCurrentTransactionElseCreateNew(()->pm.refresh(pojo))
-        .optionalElseFail();
+        .ifFailureFail();
 
         //TODO integrate with entity change tracking
     }
@@ -376,7 +376,7 @@ implements EntityFacet {
                 ()->_NullSafe.stream(fetcher.get())
                     .map(fetchedObject->adopt(entityChangeTracker, fetchedObject))
                     .collect(Can.toCan()))
-                .presentElseFail();
+                .getValue().orElseThrow();
     }
 
     private ManagedObject adopt(final EntityChangeTracker entityChangeTracker, final Object fetchedObject) {
diff --git a/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/persistence/jdo/JdoExceptionTranslationTest_usingTransactional.java b/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/persistence/jdo/JdoExceptionTranslationTest_usingTransactional.java
index 5afb2c2301..0887694019 100644
--- a/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/persistence/jdo/JdoExceptionTranslationTest_usingTransactional.java
+++ b/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/persistence/jdo/JdoExceptionTranslationTest_usingTransactional.java
@@ -99,7 +99,7 @@ extends RegressionTestAbstract {
                 .ifSuccess(__->fail("expected to fail, but did not"))
                 //.mapFailure(ex->_JdoExceptionTranslator.translate(ex, txManager))
                 .ifFailure(ex->assertTrue(ex instanceof DataIntegrityViolationException))
-                .optionalElseFail();
+                .ifFailureFail();
 
             });
 
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaExceptionTranslationTest_usingTransactional.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaExceptionTranslationTest_usingTransactional.java
index 9765cfcd5f..2125b6b343 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaExceptionTranslationTest_usingTransactional.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaExceptionTranslationTest_usingTransactional.java
@@ -99,7 +99,7 @@ extends RegressionTestAbstract {
                 .ifSuccess(__->fail("expected to fail, but did not"))
                // .mapFailure(ex->_JpaExceptionTranslator.translate(ex, txManager))
                 .ifFailure(ex->assertTrue(ex instanceof DataIntegrityViolationException))
-                .optionalElseFail();
+                .ifFailureFail();
 
             });
 
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/RegressionTestAbstract.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/RegressionTestAbstract.java
index e921201018..96de7e4806 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/RegressionTestAbstract.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/RegressionTestAbstract.java
@@ -42,13 +42,13 @@ public abstract class RegressionTestAbstract {
     protected void run(final ThrowingRunnable runnable) {
         transactionService.runTransactional(Propagation.REQUIRES_NEW, ()->
             interactionService.runAnonymous(runnable))
-        .optionalElseFail();
+        .ifFailureFail();
     }
 
     protected <T> T call(final Callable<T> callable) {
         return transactionService.callTransactional(Propagation.REQUIRES_NEW, ()->
             interactionService.callAnonymous(callable))
-        .presentElseFail();
+        .getValue().orElseThrow(); //XXX assuming return value of callable is not nullable
     }
 
     // -- ASSERTIONS
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
index 846f5b95de..9ed222c2cc 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
@@ -458,8 +458,8 @@ public class FixtureScripts {
                 runBuilderScriptNonTransactional(builderScript)
             )
         )
-        .optionalElseFail()
-        .orElse(null);
+        .ifFailureFail()
+        .getValue().orElse(null);
     }
 
     /**
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
index 5b321855c7..96b9ef109f 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
@@ -386,7 +386,7 @@ public class IsisRestfulObjectsInteractionFilter implements Filter {
                             transactionService.runWithinCurrentTransactionElseCreateNew(()->
                                 chain.doFilter(request, response))
                             .mapFailure(e->new TransactionalException("", e))
-                            .optionalElseFail();
+                            .ifFailureFail();
                         });
 
                 return;