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>")) + : ""; + } + }
