This is an automated email from the ASF dual-hosted git repository.
vlamp pushed a commit to branch TAP5-1733
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
The following commit(s) were added to refs/heads/TAP5-1733 by this push:
new 604c4ac7e TAP5-1733: Gracefully deal with FormsRequirePostException in
prod mode.
604c4ac7e is described below
commit 604c4ac7e52e3a732157928c6193f0d04c5179da
Author: Volker Lamp <[email protected]>
AuthorDate: Sun Apr 30 12:35:29 2023 +0200
TAP5-1733: Gracefully deal with FormsRequirePostException in prod mode.
---
.../FormsRequirePostExceptionHandlerAssistant.java | 61 +++++++++++++++++++++
.../apache/tapestry5/modules/TapestryModule.java | 13 ++++-
...msRequirePostExceptionHandlerAssistantTest.java | 63 ++++++++++++++++++++++
.../ioc/internal/OperationTrackerImpl.java | 17 ++++--
4 files changed, 150 insertions(+), 4 deletions(-)
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/FormsRequirePostExceptionHandlerAssistant.java
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/FormsRequirePostExceptionHandlerAssistant.java
new file mode 100644
index 000000000..4ea0150e0
--- /dev/null
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/FormsRequirePostExceptionHandlerAssistant.java
@@ -0,0 +1,61 @@
+// Copyright 2023 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.internal;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.ExceptionHandlerAssistant;
+import org.apache.tapestry5.SymbolConstants;
+import org.apache.tapestry5.commons.util.FormsRequirePostException;
+import org.apache.tapestry5.corelib.components.Form;
+import org.apache.tapestry5.services.ComponentSource;
+import org.apache.tapestry5.services.PageRenderLinkSource;
+import org.apache.tapestry5.services.RequestExceptionHandler;
+
+/**
+ * Handles {@link FormsRequirePostException}s (thrown by the {@link Form}
component when the request method was
+ * other than post) by redirecting to the page containing the form.
+ * <p>
+ * This assistant is contributed to the default {@link
RequestExceptionHandler} service in a way that it is
+ * effective only in production mode.
+ *
+ * @see ExceptionHandlerAssistant
+ * @see RequestExceptionHandler
+ * @see SymbolConstants#PRODUCTION_MODE
+ */
+public class FormsRequirePostExceptionHandlerAssistant implements
ExceptionHandlerAssistant
+{
+ final ComponentSource componentSource;
+
+ final PageRenderLinkSource linkSource;
+
+ public FormsRequirePostExceptionHandlerAssistant(final ComponentSource
componentSource, final PageRenderLinkSource linkSource)
+ {
+ this.componentSource = componentSource;
+ this.linkSource = linkSource;
+ }
+
+ @Override
+ public Object handleRequestException(Throwable exception, List<Object>
exceptionContext) throws IOException
+ {
+ ComponentResources cr =
componentSource.getActivePage().getComponentResources();
+
+ String pageName = cr.getPageName();
+
+ return linkSource.createPageRenderLink(pageName);
+ }
+}
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
index 34b9bec4c..4ec381c16 100644
---
a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
@@ -103,6 +103,7 @@ import org.apache.tapestry5.commons.services.PropertyAccess;
import org.apache.tapestry5.commons.services.TypeCoercer;
import org.apache.tapestry5.commons.util.AvailableValues;
import org.apache.tapestry5.commons.util.CollectionFactory;
+import org.apache.tapestry5.commons.util.FormsRequirePostException;
import org.apache.tapestry5.commons.util.StrategyRegistry;
import org.apache.tapestry5.corelib.data.SecureOption;
import org.apache.tapestry5.grid.GridConstants;
@@ -127,6 +128,7 @@ import org.apache.tapestry5.http.services.Session;
import org.apache.tapestry5.internal.ComponentOverrideImpl;
import org.apache.tapestry5.internal.DefaultNullFieldStrategy;
import org.apache.tapestry5.internal.DefaultValueLabelProvider;
+import org.apache.tapestry5.internal.FormsRequirePostExceptionHandlerAssistant;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.InternalSymbols;
import org.apache.tapestry5.internal.PropertyOverridesImpl;
@@ -2812,5 +2814,14 @@ public final class TapestryModule
return info;
}
}
-
+
+ // TAP5-1733
+ @Contribute(RequestExceptionHandler.class)
+ public static void
gracefullyHandleFormsRequirePostException(MappedConfiguration<Class, Object>
configuration,
+ @Symbol(TapestryHttpSymbolConstants.PRODUCTION_MODE) boolean
productionMode)
+ {
+ if (productionMode)
+ configuration.addInstance(FormsRequirePostException.class,
FormsRequirePostExceptionHandlerAssistant.class);
+ }
+
}
diff --git
a/tapestry-core/src/test/java/org/apache/tapestry5/internal/FormsRequirePostExceptionHandlerAssistantTest.java
b/tapestry-core/src/test/java/org/apache/tapestry5/internal/FormsRequirePostExceptionHandlerAssistantTest.java
new file mode 100644
index 000000000..40e7df6df
--- /dev/null
+++
b/tapestry-core/src/test/java/org/apache/tapestry5/internal/FormsRequirePostExceptionHandlerAssistantTest.java
@@ -0,0 +1,63 @@
+// Copyright 2023 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.internal;
+
+import java.io.IOException;
+
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.commons.util.FormsRequirePostException;
+import org.apache.tapestry5.http.Link;
+import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.services.ComponentSource;
+import org.apache.tapestry5.services.PageRenderLinkSource;
+import org.apache.tapestry5.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class FormsRequirePostExceptionHandlerAssistantTest extends
TapestryTestCase
+{
+ @Test
+ public void foo()
+ {
+ ComponentSource componentSource = newMock(ComponentSource.class);
+ Component page = newMock(Component.class);
+ ComponentResources componentResources = mockComponentResources();
+ PageRenderLinkSource linkSource = mockPageRenderLinkSource();
+ Link link = mockLink("/foo");
+
+ expect(componentSource.getActivePage()).andReturn(page).atLeastOnce();
+
expect(page.getComponentResources()).andReturn(componentResources).atLeastOnce();
+ train_getPageName(componentResources, "foo");
+
+
expect(linkSource.createPageRenderLink("foo")).andReturn(link).atLeastOnce();
+
+ replay();
+
+ FormsRequirePostExceptionHandlerAssistant assistant = new
FormsRequirePostExceptionHandlerAssistant(componentSource, linkSource);
+
+ FormsRequirePostException exception = new
FormsRequirePostException("doesn't matter", null);
+
+ try
+ {
+ Link l = (Link) assistant.handleRequestException(exception, null);
+ assertEquals(l.toURI(), link.toURI());
+ }
+ catch (IOException e)
+ {
+ fail();
+ }
+
+ verify();
+ }
+}
diff --git
a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/OperationTrackerImpl.java
b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/OperationTrackerImpl.java
index 067b56023..1170548b5 100644
---
a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/OperationTrackerImpl.java
+++
b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/OperationTrackerImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2008-2013 The Apache Software Foundation
+// Copyright 2008-2013, 2023 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ package org.apache.tapestry5.ioc.internal;
import org.apache.tapestry5.commons.util.CollectionFactory;
import org.apache.tapestry5.commons.util.ExceptionUtils;
+import org.apache.tapestry5.commons.util.FormsRequirePostException;
import org.apache.tapestry5.commons.util.Stack;
import org.apache.tapestry5.ioc.IOOperation;
import org.apache.tapestry5.ioc.Invokable;
@@ -87,7 +88,7 @@ public class OperationTrackerImpl implements OperationTracker
} catch (RuntimeException ex)
{
- return logAndRethrow(ex);
+ return handleRuntimeException(ex);
} catch (Error ex)
{
return handleError(ex);
@@ -115,7 +116,7 @@ public class OperationTrackerImpl implements
OperationTracker
} catch (RuntimeException ex)
{
- return logAndRethrow(ex);
+ return handleRuntimeException(ex);
} catch (Error ex)
{
return handleError(ex);
@@ -128,6 +129,16 @@ public class OperationTrackerImpl implements
OperationTracker
}
}
+ private <T> T handleRuntimeException(RuntimeException ex)
+ {
+ // This is to prevent the error level log messages
+ if (ExceptionUtils.findCause(ex, FormsRequirePostException.class) !=
null)
+ // pass through without logging
+ throw ex;
+ else
+ return logAndRethrow(ex);
+ }
+
private void handleFinally()
{
operations.pop();