diff --git a/spring-webflow/changelog.txt b/spring-webflow/changelog.txt
index 332a27b7..b53abfa4 100644
--- a/spring-webflow/changelog.txt
+++ b/spring-webflow/changelog.txt
@@ -22,6 +22,10 @@ Package org.springframework.webflow.conversation
* The SessionBindingConversationManager now re-binds the ConversationContainer in the session
every time a contained conversation is unlocked (SWF-244).
+Package org.springframework.webflow.engine
+* FlowExecutionImpl.handleException() now also tries to handle FlowExecutionExceptions that
+ occur during exception handling (SWF-261).
+
Package org.springframework.webflow.execution
* Added FlowExecutionListener.sessionCreated(RequestContext, FlowSession) callback, useful for
setting flow attributes before the flow starts (SWF-223).
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/FlowExecutionImpl.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/FlowExecutionImpl.java
index 3ded37d6..918aea9e 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/FlowExecutionImpl.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/FlowExecutionImpl.java
@@ -307,14 +307,20 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
if (logger.isDebugEnabled()) {
logger.debug("Attempting to handle [" + exception + "]");
}
- // the state could be null if the flow was attempting a start operation
- ViewSelection selectedView = tryStateHandlers(exception, context);
- if (selectedView != null) {
- return selectedView;
+ try {
+ // the state could be null if the flow was attempting a start operation
+ ViewSelection selectedView = tryStateHandlers(exception, context);
+ if (selectedView != null) {
+ return selectedView;
+ }
+ selectedView = tryFlowHandlers(exception, context);
+ if (selectedView != null) {
+ return selectedView;
+ }
}
- selectedView = tryFlowHandlers(exception, context);
- if (selectedView != null) {
- return selectedView;
+ catch (FlowExecutionException newException) {
+ // exception handling resulted in a new FlowExecutionException, try to handle it
+ return handleException(newException, context);
}
if (logger.isDebugEnabled()) {
logger.debug("Rethrowing unhandled flow execution exception");
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/ExceptionThrowingAction.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/ExceptionThrowingAction.java
new file mode 100644
index 00000000..bbd92d1e
--- /dev/null
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/ExceptionThrowingAction.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2004-2007 the original author or authors.
+ *
+ * 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.springframework.webflow.engine.impl;
+
+import org.springframework.webflow.action.AbstractAction;
+import org.springframework.webflow.execution.Event;
+import org.springframework.webflow.execution.RequestContext;
+
+/**
+ * Test action that throws an exception.
+ *
+ * @author Erwin Vervaet
+ */
+public class ExceptionThrowingAction extends AbstractAction {
+
+ protected Event doExecute(RequestContext context) throws Exception {
+ Class exceptionType = Class.forName(context.getAttributes().getString("exceptionType"));
+ throw (Exception)exceptionType.newInstance();
+ }
+
+}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/FlowExecutionImplTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/FlowExecutionImplTests.java
index 823c9550..688ee1ea 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/FlowExecutionImplTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/FlowExecutionImplTests.java
@@ -50,8 +50,10 @@ import org.springframework.webflow.execution.FlowExecutionListener;
import org.springframework.webflow.execution.MockFlowExecutionListener;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.TestAction;
+import org.springframework.webflow.execution.ViewSelection;
import org.springframework.webflow.execution.support.ApplicationView;
import org.springframework.webflow.test.MockExternalContext;
+import org.springframework.webflow.test.MockFlowServiceLocator;
/**
* General flow execution tests.
@@ -61,6 +63,19 @@ import org.springframework.webflow.test.MockExternalContext;
* @author Ben Hale
*/
public class FlowExecutionImplTests extends TestCase {
+
+ public void testExceptionWhileHandlingException() {
+ MockFlowServiceLocator serviceLocator = new MockFlowServiceLocator();
+ serviceLocator.registerBean("testAction", new ExceptionThrowingAction());
+ XmlFlowBuilder flowBuilder =
+ new XmlFlowBuilder(new ClassPathResource("exceptionHandlingFlow.xml", this.getClass()));
+ flowBuilder.setFlowServiceLocator(serviceLocator);
+ Flow flow = new FlowAssembler("flow", flowBuilder).assembleFlow();
+ FlowExecution flowExecution = new FlowExecutionImpl(flow);
+ ViewSelection view = flowExecution.start(null, new MockExternalContext());
+ assertEquals("failed", ((ApplicationView)view).getViewName());
+ assertFalse(flowExecution.isActive());
+ }
public void testFlowExecutionListener() {
Flow flow = new Flow("myFlow");
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/exceptionHandlingFlow.xml b/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/exceptionHandlingFlow.xml
new file mode 100644
index 00000000..19aa440a
--- /dev/null
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/exceptionHandlingFlow.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/testFlow.xml b/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/testFlow.xml
index 31ea9ebb..591f0347 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/testFlow.xml
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/impl/testFlow.xml
@@ -1,7 +1,9 @@
-
-
-
+
+
+