Skip to content

Commit 64af5a3

Browse files
authored
Add step location in case of datatable conversion error (#2908)
1 parent 5843e58 commit 64af5a3

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
## [Unreleased]
1313

14+
### Fixed
15+
- [Core] Enhanced stack trace to include step location for better debugging in case of datatable conversion errors ([#2908](https://github.com/cucumber/cucumber-jvm/pull/2908) Thomas Deblock)
16+
1417
## [7.18.1] - 2024-07-18
1518
### Changed
1619
- [Core] Include parameterized scenario name in JUnit and TestNG XML report

cucumber-core/src/main/java/io/cucumber/core/runner/PickleStepDefinitionMatch.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.util.List;
1919
import java.util.stream.Collectors;
2020

21-
import static io.cucumber.core.runner.StackManipulation.removeFrameworkFrames;
2221
import static io.cucumber.core.runner.StackManipulation.removeFrameworkFramesAndAppendStepLocation;
2322

2423
class PickleStepDefinitionMatch extends Match implements StepDefinitionMatch {
@@ -51,13 +50,13 @@ public void runStep(TestCaseState state) throws Throwable {
5150
} catch (CucumberExpressionException | CucumberDataTableException | CucumberDocStringException e) {
5251
CucumberInvocationTargetException targetException;
5352
if ((targetException = causedByCucumberInvocationTargetException(e)) != null) {
54-
throw removeFrameworkFrames(targetException);
53+
throw removeFrameworkFramesAndAppendStepLocation(targetException, getStepLocation());
5554
}
5655
throw couldNotConvertArguments(e);
5756
} catch (CucumberBackendException e) {
5857
throw couldNotInvokeArgumentConversion(e);
5958
} catch (CucumberInvocationTargetException e) {
60-
throw removeFrameworkFrames(e);
59+
throw removeFrameworkFramesAndAppendStepLocation(e, getStepLocation());
6160
}
6261
try {
6362
stepDefinition.execute(result.toArray(new Object[0]));

cucumber-core/src/test/java/io/cucumber/core/runner/StepDefinitionMatchTest.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,15 @@ void rethrows_target_invocation_exceptions_from_parameter_type() {
257257
StepExpression expression = stepExpressionFactory.createExpression(stepDefinition);
258258
CoreStepDefinition coreStepDefinition = new CoreStepDefinition(id, stepDefinition, expression);
259259
List<Argument> arguments = coreStepDefinition.matchedArguments(step);
260-
StepDefinitionMatch stepDefinitionMatch = new PickleStepDefinitionMatch(arguments, stepDefinition, null, step);
260+
StepDefinitionMatch stepDefinitionMatch = new PickleStepDefinitionMatch(arguments, stepDefinition,
261+
URI.create("test.feature"), step);
261262

262263
Executable testMethod = () -> stepDefinitionMatch.runStep(null);
263264
RuntimeException actualThrown = assertThrows(RuntimeException.class, testMethod);
264265
assertThat(actualThrown, sameInstance(userException));
266+
assertThat(
267+
lastStackElement(actualThrown.getStackTrace()),
268+
is(new StackTraceElement("✽", "I have some cukes in my belly", "test.feature", 3)));
265269
}
266270

267271
@Test
@@ -312,11 +316,15 @@ void rethrows_target_invocation_exceptions_from_data_table() {
312316
StepExpression expression = stepExpressionFactory.createExpression(stepDefinition);
313317
CoreStepDefinition coreStepDefinition = new CoreStepDefinition(id, stepDefinition, expression);
314318
List<Argument> arguments = coreStepDefinition.matchedArguments(step);
315-
StepDefinitionMatch stepDefinitionMatch = new PickleStepDefinitionMatch(arguments, stepDefinition, null, step);
319+
StepDefinitionMatch stepDefinitionMatch = new PickleStepDefinitionMatch(arguments, stepDefinition,
320+
URI.create("test.feature"), step);
316321

317322
Executable testMethod = () -> stepDefinitionMatch.runStep(null);
318323
RuntimeException actualThrown = assertThrows(RuntimeException.class, testMethod);
319324
assertThat(actualThrown, sameInstance(userException));
325+
assertThat(
326+
lastStackElement(actualThrown.getStackTrace()),
327+
is(new StackTraceElement("✽", "I have some cukes in my belly", "test.feature", 3)));
320328
}
321329

322330
@Test
@@ -367,11 +375,15 @@ void rethrows_target_invocation_exception_for_docstring() {
367375
StepExpression expression = stepExpressionFactory.createExpression(stepDefinition);
368376
CoreStepDefinition coreStepDefinition = new CoreStepDefinition(id, stepDefinition, expression);
369377
List<Argument> arguments = coreStepDefinition.matchedArguments(step);
370-
StepDefinitionMatch stepDefinitionMatch = new PickleStepDefinitionMatch(arguments, stepDefinition, null, step);
378+
StepDefinitionMatch stepDefinitionMatch = new PickleStepDefinitionMatch(arguments, stepDefinition,
379+
URI.create("test.feature"), step);
371380

372381
Executable testMethod = () -> stepDefinitionMatch.runStep(null);
373382
RuntimeException actualThrown = assertThrows(RuntimeException.class, testMethod);
374383
assertThat(actualThrown, sameInstance(userException));
384+
assertThat(
385+
lastStackElement(actualThrown.getStackTrace()),
386+
is(new StackTraceElement("✽", "I have some cukes in my belly", "test.feature", 3)));
375387
}
376388

377389
@Test
@@ -465,6 +477,10 @@ void throws_could_not_invoke_step_when_execution_failed_with_null_arguments() {
465477
"The converted arguments types were (null)")));
466478
}
467479

480+
private StackTraceElement lastStackElement(StackTraceElement[] stackTrace) {
481+
return stackTrace[stackTrace.length - 1];
482+
}
483+
468484
private static final class ItemQuantity {
469485

470486
private final String s;

0 commit comments

Comments
 (0)