question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cornichon fails silently when exception is raised in hooks

See original GitHub issue

I was fighting with my scenario when it occurs to me, that my afterFeature hook may raise an error (in case of errors in the scenario, some resources are not clean for now).

As Cornichon is a test framework, I expected that when an exception happened, I know at least which exception happened and in which block, but I only had a basic message that my feature is unsuccessful.

Considering this code:

import com.github.agourlay.cornichon.CornichonFeature
import com.github.agourlay.cornichon.core.FeatureDef
import com.github.agourlay.cornichon.steps.regular.DebugStep

class ExceptionFeature extends CornichonFeature {
  override def feature: FeatureDef = Feature("Sample") {
    Scenario("Dummy") {
      When I DebugStep("do nothing", _ => Right("always successful"))
    }
  }

  afterFeature {
    throw new Exception("I failed")
    ()
  }
}

The result was:

...snip compilation...
[info] Done compiling.
Starting scenario 'Dummy'
[error] Error: Total 2, Failed 0, Errors 1, Passed 1
[error] Error during tests:
[error] 	ExceptionFeature
[error] (Test / testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 9 s, completed Jul 7, 2020 3:24:28 PM

Process finished with exit code 1

Expectation

The exception is caught and we can see the report with an obvious error case in afterFeature block about raising an java.lang.Exception exception with the message “I failed”. Kudos if the stack trace is meaningful.

Workaround

Once I found that the issue was with exceptions, I overridden beforeFeature and afterFeature as following:

import scala.util.Try

import com.github.agourlay.cornichon.CornichonFeature
import org.log4s._

trait CustomCornichonFeature extends CornichonFeature {

  override def beforeFeature(before: => Unit): Unit = {
    super.beforeFeature {
      logButRethrow(before, "Exception during beforeFeature")
    }
  }

  override def afterFeature(after: => Unit): Unit = super.afterFeature {
    logButRethrow(after, "Exception during afterFeature")
  }

  private def logButRethrow(before: => Unit, msg: String): Unit = {
    Try(before).fold(t => {
      getLogger.error(t)(msg)
      throw t
    }, identity)
  }
}

Notes:

  • I don’t like to rethrow the exception. But I think it is necessary for now to be able to handle the failure case (and not beginning the real feature / the scenarios if setUp failed in beforeFeature block)
  • I am not sure that log4s is a dependency of Cornichon or my own project.
  • In real implementation, I don’t know if we have to manage each block in isolation or if the first failed, we do not let the others to execute.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
agourlaycommented, Jul 15, 2020

I am really happy to have harden this part of the lib 🔨

Please give it a try to check if it handles your case and has a clear error reporting.

1reaction
Isammoccommented, Jul 15, 2020

Thank you to have took this into account. And for the fix.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handling exceptions in SpecFlow | Ronald's Blog
I use Gherkin scenarios to describe the functional specifications of my ... IsNotNull(_actualException, "No error was raised"); Assert.
Read more >
Calling a hook function every time an Exception is raised
If you want to log uncaught exceptions, just use sys.excepthook. I'm not sure I see the value of logging all raised exceptions, since...
Read more >
ValueError exceptions in hooks are not properly handled #43
If a ValueError is raised inside a hook (which was the case above) no traceback is printed (and the exception is not passed...
Read more >
How to Handle Exceptions in Ruby - Rollbar
The simple guide to exception handling in Ruby. ✓ Harden your app against unexpected errors ✓ Respond more effectively ✓ Adapt to any ......
Read more >
Do I raise or return errors in Python? - victoria.dev
Raise can help you avoid writing functions that fail silently. For example, this code will not raise an exception if JAM doesn't exist:....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found