Our logic cancels Stories after they time out. Sometimes at least.  The
communication is poor though it'll come back as a UUIDExceptionWrapper
wrapping a WebDriverException wrapping a InterruptedException.  That's just
for situations where WebDriver is part of a chain, and the interruption was
during a over-the-wire selenium operation.

What do you think of the following change Mauro ?

1) Maintain a list of stores that are cancelled.
2) replace the exception thrown/caught with one that's clearer as to a
correlation with a cancellation.

Like so:

diff --git
a/jbehave-core/src/main/java/org/jbehave/core/embedder/Embedder.java
b/jbehave-core/src/main/java/org/jbehave/core/embedder/Embedder.java
index fd8d6f1..00c11e4 100755
--- a/jbehave-core/src/main/java/org/jbehave/core/embedder/Embedder.java
+++ b/jbehave-core/src/main/java/org/jbehave/core/embedder/Embedder.java
@@ -3,8 +3,10 @@ package org.jbehave.core.embedder;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Properties;
+import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -53,6 +55,7 @@ public class Embedder {
     private StoryRunner storyRunner;
     private EmbedderMonitor embedderMonitor;
     private ExecutorService executorService;
+    private Set<String> cancelled = new HashSet<String>();

     public Embedder() {
         this(new StoryMapper(), new StoryRunner(), new
PrintStreamEmbedderMonitor());
@@ -258,7 +261,7 @@ public class Embedder {
             InjectableStepsFactory stepsFactory, BatchFailures
batchFailures, MetaFilter filter, String storyPath,
             Story story, State beforeStories) {
         return new EnqueuedStory(storyPath, configuration, stepsFactory,
story, filter, embedderControls,
-                batchFailures, embedderMonitor, storyRunner,
beforeStories);
+                batchFailures, embedderMonitor, storyRunner,
beforeStories, cancelled);
     }

     /**
@@ -294,6 +297,7 @@ public class Embedder {
                             }
                         }
                         embedderMonitor.storyTimeout(story,
durationInSecs, timeoutInSecs);
+                        cancelled.add(story.getPath());
                         future.cancel(true);
                     }
                     try {
@@ -592,16 +596,18 @@ public class Embedder {
         private final EmbedderMonitor embedderMonitor;
         private final StoryRunner storyRunner;
         private final State beforeStories;
+        private final Set<String> cancelled;

         public EnqueuedStory(String storyPath, Configuration
configuration, List<CandidateSteps> candidateSteps,
                 Story story, MetaFilter filter, EmbedderControls
embedderControls, BatchFailures batchFailures,
-                EmbedderMonitor embedderMonitor, StoryRunner storyRunner,
State beforeStories) {
-            this(storyPath, configuration, new
ProvidedStepsFactory(candidateSteps), story, filter, embedderControls,
batchFailures, embedderMonitor, storyRunner, beforeStories);
+                EmbedderMonitor embedderMonitor, StoryRunner storyRunner,
State beforeStories, Set<String> cancelled) {
+            this(storyPath, configuration, new
ProvidedStepsFactory(candidateSteps), story, filter, embedderControls,
+                    batchFailures, embedderMonitor, storyRunner,
beforeStories, cancelled);
         }

         public EnqueuedStory(String storyPath, Configuration
configuration, InjectableStepsFactory stepsFactory,
                 Story story, MetaFilter filter, EmbedderControls
embedderControls, BatchFailures batchFailures,
-                EmbedderMonitor embedderMonitor, StoryRunner storyRunner,
State beforeStories) {
+                EmbedderMonitor embedderMonitor, StoryRunner storyRunner,
State beforeStories, Set<String> cancelled) {
             this.storyPath = storyPath;
             this.configuration = configuration;
             this.stepsFactory = stepsFactory;
@@ -612,6 +618,7 @@ public class Embedder {
             this.embedderMonitor = embedderMonitor;
             this.storyRunner = storyRunner;
             this.beforeStories = beforeStories;
+            this.cancelled = cancelled;
         }

         public ThrowableStory call() throws Exception {
@@ -619,6 +626,9 @@ public class Embedder {
                 embedderMonitor.runningStory(storyPath);
                 storyRunner.run(configuration, stepsFactory, story,
filter, beforeStories);
             } catch (Throwable e) {
+                if (cancelled.contains(story.getPath())) {
+                    e = new StoryCancelledAsItWasTakingTooLong();
+                }
                 if (embedderControls.batch()) {
                     // collect and postpone decision to throw exception
                     batchFailures.put(storyPath, e);
@@ -633,6 +643,9 @@ public class Embedder {
             return new ThrowableStory(null, story);
         }
     }
+
+    public static class StoryCancelledAsItWasTakingTooLong extends
RuntimeException {
+    }

     public static class ThrowableStory {
         private Throwable throwable;

Reply via email to