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/causeway.git

commit 5e0854443e737d54ed448b39252cbd007a9bb126
Author: andi-huber <[email protected]>
AuthorDate: Sun Feb 4 18:14:14 2024 +0100

    CAUSEWAY-3404: improved error message on action returning
    non-bookmarkable object
---
 .../core/config/progmodel/ProgrammingModelConstants.java    | 11 +++++++++++
 .../executor/MemberExecutorServiceDefault.java              | 13 +++++++++++--
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git 
a/core/config/src/main/java/org/apache/causeway/core/config/progmodel/ProgrammingModelConstants.java
 
b/core/config/src/main/java/org/apache/causeway/core/config/progmodel/ProgrammingModelConstants.java
index f5601fc23a..0153c06cae 100644
--- 
a/core/config/src/main/java/org/apache/causeway/core/config/progmodel/ProgrammingModelConstants.java
+++ 
b/core/config/src/main/java/org/apache/causeway/core/config/progmodel/ProgrammingModelConstants.java
@@ -466,6 +466,14 @@ public final class ProgrammingModelConstants {
         UNKNONW_SORT_WITH_ACTION("${type}: is a (concrete) but UNKNOWN sort, 
yet has ${actionCount} actions: ${actions}"),
         ACTION_METHOD_OVERLOADING_NOT_ALLOWED("Action method overloading is 
not allowed, "
                 + "yet ${type} has action(s) that have a the same member name: 
${overloadedNames}"),
+        ACTION_METHOD_RETURNING_TRANSIENT_ENTITY_NOT_ALLOWED("Action methods 
are not allowed to return transient entities, "
+                + "yet ${type} has action ${memberId}, which did return a 
transient entity of type ${returnTypeSpec}. "
+                + "To correct this issue either persist the entity within 
above method before returning it, "
+                + "or don't have the method invocation managed by the 
framework, e.g. "
+                + "mark the method @Programmatic."),
+        ACTION_METHOD_RETURNING_NON_BOOKMARKABLE_OBJECT_NOT_ALLOWED("Action 
methods are not allowed to return objects, "
+                + "for which no bookmark can be created, "
+                + "yet ${type} has action ${memberId}, which did return such 
an object of type ${returnTypeSpec}."),
         PARAMETER_HAS_NO_CHOICES_NOR_AUTOCOMPLETE("${paramId} has no choices 
nor autoComplete, "
                 + "yet represents a domain-object or is a plural."),
         PARAMETER_TUPLE_INVALID_USE_OF_ANNOTATION("${type}#${member}: "
@@ -509,6 +517,9 @@ public final class ProgrammingModelConstants {
                 vars.put(name, ""+value);
                 return this;
             }
+            /**
+             * Populates 'type' and 'member' keys (for template variable 
resolution).
+             */
             public ViolationBuilder addVariablesFor(final Identifier 
featureIdentifier) {
                 addVariable("type", 
featureIdentifier.getLogicalType().getClassName());
                 addVariable("member", 
featureIdentifier.getMemberLogicalName());
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
index 9604353aeb..dadf8c71de 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
@@ -44,6 +44,7 @@ import 
org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.internal.collections._Lists;
 import 
org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade;
 import org.apache.causeway.core.config.CausewayConfiguration;
+import 
org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.Violation;
 import org.apache.causeway.core.metamodel.commons.CanonicalInvoker;
 import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.causeway.core.metamodel.execution.ActionExecutor;
@@ -184,8 +185,16 @@ implements MemberExecutorService {
             return true;
         })
         .ifPresent(scalarNonEmpty->{
-            _Assert.assertTrue(scalarNonEmpty.getBookmark().isPresent(), 
()->String.format(
-                    "bookmark required for non-empty scalars %s", 
scalarNonEmpty.getSpecification()));
+            _Assert.assertTrue(scalarNonEmpty.getBookmark().isPresent(), ()->{
+                var returnTypeSpec = scalarNonEmpty.getSpecification();
+                var violation = returnTypeSpec.isEntity()
+                        ? 
Violation.ACTION_METHOD_RETURNING_TRANSIENT_ENTITY_NOT_ALLOWED
+                        : 
Violation.ACTION_METHOD_RETURNING_NON_BOOKMARKABLE_OBJECT_NOT_ALLOWED;
+                return violation.builder()
+                    .addVariablesFor(actionId)
+                    .addVariable("returnTypeSpec", returnTypeSpec.toString())
+                    .buildMessage();
+            });
         });
 
         // sync DTO with result

Reply via email to