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

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

commit 949d49b7f53429cee1f203a412d6fd8b48642a6f
Author: Andi Huber <[email protected]>
AuthorDate: Wed Sep 3 12:16:19 2025 +0200

    CAUSEWAY-3892: improved exception rendering (also fixes pot. NPE)
---
 .../wicket/ui/errors/ExceptionStackTracePanel.java | 48 ++++++++++++++--------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/errors/ExceptionStackTracePanel.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/errors/ExceptionStackTracePanel.java
index dec85777403..8e2b34f34a5 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/errors/ExceptionStackTracePanel.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/errors/ExceptionStackTracePanel.java
@@ -18,6 +18,7 @@
  */
 package org.apache.causeway.viewer.wicket.ui.errors;
 
+import java.util.Objects;
 import java.util.stream.Stream;
 
 import org.apache.wicket.AttributeModifier;
@@ -32,10 +33,13 @@
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 
+import org.springframework.util.StringUtils;
+
 import org.apache.causeway.applib.services.error.ErrorReportingService;
 import org.apache.causeway.applib.services.error.Ticket;
 import org.apache.causeway.commons.functional.IndexedConsumer;
 import org.apache.causeway.commons.functional.Try;
+import org.apache.causeway.commons.internal.base._NullSafe;
 import org.apache.causeway.viewer.commons.model.error.ExceptionModel;
 import org.apache.causeway.viewer.wicket.model.models.PageType;
 import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt;
@@ -148,25 +152,33 @@ public void renderHead(final IHeaderResponse response) {
 
     private static String convertToHtml(ExceptionModel exceptionModel) {
         var html = new StringBuilder();
-        exceptionModel.causalChain().forEach(IndexedConsumer.zeroBased((i, 
cause)->{
-            if(i>0) html.append("<hr>");
-            html.append("<div>%s<b>%s</b>: %s</div>".formatted(
-                i>0 ? "Caused by: " : "",
-                cause.getClass().getName(),
-                
org.springframework.web.util.HtmlUtils.htmlEscape(cause.getMessage())));
-
-            Stream.of(cause.getStackTrace()).forEach(el->{
-                html.append("""
-                    <div style="margin-left: 1rem">at %s#%s(%s:%d)</div>"""
-                    .formatted(
-                        el.getClassName(),
-                        el.getMethodName(),
-                        el.getFileName(),
-                        el.getLineNumber()));
-            });
-
-        }));
+        _NullSafe.stream(exceptionModel.causalChain())
+            .filter(Objects::nonNull)
+            .forEach(IndexedConsumer.zeroBased((i, cause)->{
+                if(i>0) html.append("<hr>");
+                html.append("<div>%s<b>%s</b>: %s</div>".formatted(
+                    i>0 ? "Caused by: " : "",
+                    cause.getClass().getName(),
+                    convertMessageToHtml(cause)));
+
+                Stream.of(cause.getStackTrace()).forEach(el->{
+                    html.append("""
+                        <div style="margin-left: 1rem">at %s#%s(%s:%d)</div>"""
+                        .formatted(
+                            el.getClassName(),
+                            el.getMethodName(),
+                            el.getFileName(),
+                            el.getLineNumber()));
+                });
+
+            }));
         return html.toString();
     }
 
+    private static String convertMessageToHtml(Throwable cause) {
+        return StringUtils.hasLength(cause.getMessage())
+            ? 
org.springframework.web.util.HtmlUtils.htmlEscape(cause.getMessage().replace("\n",
 "<br>"))
+            : "";
+    }
+
 }

Reply via email to