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

kwin pushed a commit to branch feature/expose-persistence-exception-cause
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-api.git

commit b870036d01b0c3bf69817754d5946cb5b9ddf639
Author: Konrad Windszus <[email protected]>
AuthorDate: Thu Jun 19 16:50:35 2025 +0200

    SLING-12834 Expose the cause of PersistenceException in its getMessage()
    
    This is beneficial for cases where the stacktrace is not available (e.g.
    in UI using PersistenceException.getMessage() or
    PersistenceException.toString()) like SlingPostServlets HtmlResponse.
---
 .../sling/api/resource/PersistenceException.java   | 33 ++++++++++++++++++
 .../api/resource/PersistenceExceptionTest.java     | 40 ++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git 
a/src/main/java/org/apache/sling/api/resource/PersistenceException.java 
b/src/main/java/org/apache/sling/api/resource/PersistenceException.java
index 659005b..1e5356d 100644
--- a/src/main/java/org/apache/sling/api/resource/PersistenceException.java
+++ b/src/main/java/org/apache/sling/api/resource/PersistenceException.java
@@ -19,6 +19,7 @@
 package org.apache.sling.api.resource;
 
 import java.io.IOException;
+import java.util.Set;
 
 /**
  * This exception will be thrown during the commit to persist
@@ -29,6 +30,8 @@ public class PersistenceException extends IOException {
 
     private static final long serialVersionUID = 2454225989618227698L;
 
+    private static final Set<Character> PUNCTUATION = Set.of('.', ':', '!');
+
     /** Optional resource path. */
     private final String resourcePath;
 
@@ -91,4 +94,34 @@ public class PersistenceException extends IOException {
     public String getPropertyName() {
         return this.propertyName;
     }
+
+    /**
+     * Returns a message for this exception.
+     * If the cause is not null, it will be appended to the message.
+     * @return The message for this exception
+     */
+    @Override
+    public String getMessage() {
+        StringBuilder sb = new StringBuilder();
+        if (this.getCause() != null) {
+            sb.append(getStringWithoutTailingPunctuation(super.getMessage()))
+                    .append(" caused by ")
+                    .append(this.getCause().getMessage());
+        } else {
+            sb.append(super.getMessage());
+        }
+
+        return sb.toString();
+    }
+
+    private static String getStringWithoutTailingPunctuation(String str) {
+        if (str == null || str.isEmpty()) {
+            return str;
+        }
+        int len = str.length();
+        if (len > 0 && PUNCTUATION.contains(str.charAt(len - 1))) {
+            return str.substring(0, len - 1);
+        }
+        return str;
+    }
 }
diff --git 
a/src/test/java/org/apache/sling/api/resource/PersistenceExceptionTest.java 
b/src/test/java/org/apache/sling/api/resource/PersistenceExceptionTest.java
new file mode 100644
index 0000000..6cc04b3
--- /dev/null
+++ b/src/test/java/org/apache/sling/api/resource/PersistenceExceptionTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.sling.api.resource;
+
+import javax.jcr.RepositoryException;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class PersistenceExceptionTest {
+
+    @Test
+    public void testGetMessage() {
+        PersistenceException e = new PersistenceException("Test message");
+        assertEquals("Test message", e.getMessage());
+        e = new PersistenceException("Test message", new 
RepositoryException("JCR error"));
+        assertEquals("Test message caused by JCR error", e.getMessage());
+        e = new PersistenceException("Test message!", new 
RepositoryException("JCR error"));
+        assertEquals("Test message caused by JCR error", e.getMessage());
+        e = new PersistenceException("Test message.", new 
RepositoryException("JCR error"));
+        assertEquals("Test message caused by JCR error", e.getMessage());
+    }
+}

Reply via email to