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

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


The following commit(s) were added to refs/heads/main by this push:
     new b3f341e4c13 CAUSEWAY-3893: on retrieval errors of 
CausewayConfiguration#valueOf(..) log instead of throw
b3f341e4c13 is described below

commit b3f341e4c13dfa9d3c9883e6a7f2530d3c7a29ec
Author: Andi Huber <ahu...@apache.org>
AuthorDate: Wed May 28 04:41:29 2025 +0200

    CAUSEWAY-3893: on retrieval errors of CausewayConfiguration#valueOf(..)
    log instead of throw
---
 .../core/config/CausewayConfiguration.java         | 22 ++++++++++++++++++++++
 .../confmenu/ConfigurationViewServiceDefault.java  | 12 ++++++++++--
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git 
a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
 
b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
index 92a88f3aae4..7d41f7111cb 100644
--- 
a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
+++ 
b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
@@ -33,6 +33,7 @@
 import java.util.Objects;
 import java.util.Optional;
 import java.util.concurrent.Callable;
+import java.util.function.Consumer;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -58,6 +59,8 @@
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 
+import org.jspecify.annotations.Nullable;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import 
org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
@@ -88,6 +91,7 @@
 import org.apache.causeway.applib.services.userui.UserMenu;
 import 
org.apache.causeway.applib.value.semantics.TemporalValueSemantics.TemporalDisplayPattern;
 import 
org.apache.causeway.applib.value.semantics.TemporalValueSemantics.TemporalEditingPattern;
+import org.apache.causeway.commons.functional.Try;
 import org.apache.causeway.commons.internal.base._NullSafe;
 import org.apache.causeway.commons.internal.context._Context;
 import org.apache.causeway.core.config.metamodel.facets.ActionConfigOptions;
@@ -189,6 +193,24 @@ public Optional<String> valueOf(final String 
configurationPropertyName) {
         return 
Optional.ofNullable(environment.getProperty(configurationPropertyName));
     }
 
+    /**
+     * The value of a specific configuration property
+     *
+     * @param configurationPropertyName  - eg as obtained from {@link 
#streamConfigurationPropertyNames()}.
+        * @param onError - callback in case the value retrieval thorws any 
exception
+     */
+    public Optional<String> valueOf(final String configurationPropertyName, 
final @Nullable Consumer<Throwable> onError) {
+        try {
+                       return 
Optional.ofNullable(environment.getProperty(configurationPropertyName));
+               } catch (Throwable t) {
+                       if(onError!=null) {
+                               Try.run(()->onError.accept(t));
+                       }
+                       return Optional.empty();
+               }
+               
+    }
+
     private final Security security = new Security();
     @Data
     public static class Security {
diff --git 
a/core/webapp/src/main/java/org/apache/causeway/core/webapp/confmenu/ConfigurationViewServiceDefault.java
 
b/core/webapp/src/main/java/org/apache/causeway/core/webapp/confmenu/ConfigurationViewServiceDefault.java
index ec94c031d8d..3378420a6dd 100644
--- 
a/core/webapp/src/main/java/org/apache/causeway/core/webapp/confmenu/ConfigurationViewServiceDefault.java
+++ 
b/core/webapp/src/main/java/org/apache/causeway/core/webapp/confmenu/ConfigurationViewServiceDefault.java
@@ -192,7 +192,9 @@ private Map<String, ConfigurationProperty> 
loadPrimary(final List<String> primar
             configuration.streamConfigurationPropertyNames()
             
.filter(propName->primaryPrefixes.stream().anyMatch(propName::startsWith))
             .forEach(propName -> {
-                String propertyValue = 
configuration.valueOf(propName).orElse(null);
+                String propertyValue = configuration
+                        .valueOf(propName, ex->logRetrievalFailure(propName, 
ex))
+                        .orElse(null);
                 add(propName, propertyValue, map);
             });
 
@@ -218,7 +220,9 @@ private Map<String, ConfigurationProperty> 
loadSecondary(final Set<String> toBeE
             configuration.streamConfigurationPropertyNames()
             .filter(propName->!toBeExcluded.contains(propName))
             .forEach(propName -> {
-                String propertyValue = 
configuration.valueOf(propName).orElse(null);
+                String propertyValue = configuration
+                        .valueOf(propName, ex->logRetrievalFailure(propName, 
ex))
+                        .orElse(null);
                 add(propName, propertyValue, map);
             });
 
@@ -229,6 +233,10 @@ private Map<String, ConfigurationProperty> 
loadSecondary(final Set<String> toBeE
         }
         return map;
     }
+    
+    private static void logRetrievalFailure(final String propName, Throwable 
error) {
+        log.warn("failed to load configuration property '{}'", propName, 
error);
+    }
 
     private static void add(final String key, String value, final Map<String, 
ConfigurationProperty> map) {
         value = ValueMaskingUtil.maskIfProtected(key, value);

Reply via email to