diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/LoggingRequestCycleListener.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/LoggingRequestCycleListener.java index b6e63e6eb9b..266992aeab0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/LoggingRequestCycleListener.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/LoggingRequestCycleListener.java @@ -9,6 +9,8 @@ import org.apache.wicket.Application; import org.apache.wicket.core.request.handler.PageProvider; import org.apache.wicket.core.request.handler.RenderPageRequestHandler; +import org.apache.wicket.core.request.handler.RenderPageRequestHandler.RedirectPolicy; +import org.apache.wicket.core.request.mapper.StalePageException; import org.apache.wicket.request.IRequestHandler; import org.apache.wicket.request.Url; import org.apache.wicket.request.component.IRequestablePage; @@ -49,6 +51,14 @@ public IRequestHandler onException(RequestCycle cycle, Exception ex) { REQUEST_LOGGER.trace("REQUEST CYCLE: Exception: {}, handler {}", ex, WebComponentUtil.debugHandler(cycle.getActiveRequestHandler()), ex); } + if (ex instanceof StalePageException stalePageException) { + // Wicket uses this exception for stale render-count recovery, e.g. after browser view-source. + // Do not convert it to PageError/500, recover by re-rendering the stale page. + LOGGER.debug("Recovering stale Wicket page request by re-rendering page {}", stalePageException.getPage()); + return new RenderPageRequestHandler( + new PageProvider(stalePageException.getPage()), + RedirectPolicy.ALWAYS_REDIRECT); + } LoggingUtils.logUnexpectedException(LOGGER, "Error occurred during page rendering", ex); return new RenderPageRequestHandler(new PageProvider(new PageError(ex))); } @@ -136,4 +146,3 @@ public void onUrlMapped(RequestCycle cycle, IRequestHandler handler, Url url) { } } } - diff --git a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/LoggingRequestCycleListenerTest.java b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/LoggingRequestCycleListenerTest.java new file mode 100644 index 00000000000..9df959f9e3f --- /dev/null +++ b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/LoggingRequestCycleListenerTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010-2026 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.web; + +import com.evolveum.midpoint.web.security.LoggingRequestCycleListener; +import org.apache.wicket.core.request.handler.RenderPageRequestHandler; +import org.apache.wicket.core.request.handler.RenderPageRequestHandler.RedirectPolicy; +import org.apache.wicket.core.request.mapper.StalePageException; +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.request.IRequestHandler; +import org.apache.wicket.util.tester.WicketTester; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * Tests exception handling behavior in {@link LoggingRequestCycleListener}. + */ +public class LoggingRequestCycleListenerTest { + + /** + * MID-9998: Verifies that Wicket stale page recovery, e.g. after browser + * view-source, is handled by re-rendering the stale page instead of being + * converted to the error page / HTTP 500. + */ + @Test + public void testStalePageExceptionIsRecoveredInsteadOfConvertedToPageError() { + WicketTester tester = new WicketTester(); + try { + LoggingRequestCycleListener listener = new LoggingRequestCycleListener(tester.getApplication()); + TestPage page = new TestPage(); + + IRequestHandler handler = listener.onException(null, new StalePageException(page)); + + Assert.assertTrue(handler instanceof RenderPageRequestHandler); + + RenderPageRequestHandler renderHandler = (RenderPageRequestHandler) handler; + Assert.assertSame(renderHandler.getPage(), page); + Assert.assertSame(renderHandler.getRedirectPolicy(), RedirectPolicy.ALWAYS_REDIRECT); + } finally { + tester.destroy(); + } + } + + private static class TestPage extends WebPage { + } +} diff --git a/gui/admin-gui/testng-unit.xml b/gui/admin-gui/testng-unit.xml index 4759da96677..3caef0c5ea7 100644 --- a/gui/admin-gui/testng-unit.xml +++ b/gui/admin-gui/testng-unit.xml @@ -14,6 +14,7 @@ + diff --git a/release-notes.adoc b/release-notes.adoc index 6c212cea90d..0be0f8a2c1b 100644 --- a/release-notes.adoc +++ b/release-notes.adoc @@ -140,6 +140,7 @@ Overall, midPoint 4.10 opens up the world of identity management and governance * Fixed missing .zip extension when downloading tracing report files. See bug:MID-11096[] * Fixed resource wizard mapping property autocomplete to find partial matches regardless of letter case. See bug:MID-10415[] * Fixed missing input variable in resource activation existence mappings. See bug:MID-10905[] +* Fixed stale page recovery after viewing page source causing internal server error. See bug:MID-9998[] === Releases Of Other Components