Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOApp.reportFailure is not invoked for a NonFatal exception #3768

Closed
kamilkloch opened this issue Aug 2, 2023 · 1 comment
Closed

IOApp.reportFailure is not invoked for a NonFatal exception #3768

kamilkloch opened this issue Aug 2, 2023 · 1 comment

Comments

@kamilkloch
Copy link
Contributor

object ReportFailureApp extends IOApp.Simple {

  override protected def reportFailure(err: Throwable): IO[Unit] = IO.println(s"Failure")

  override def run: IO[Unit] = IO(throw new Exception(""))
}

prints stack trace instead of "Failure".

@armanbilge
Copy link
Member

armanbilge commented Aug 2, 2023

This is the correct and expected behavior.

/**
* Configures the action to perform when unhandled errors are caught by the runtime. By
* default, this simply delegates to [[cats.effect.std.Console!.printStackTrace]]. It is safe
* to perform any `IO` action within this handler; it will not block the progress of the
* runtime. With that said, some care should be taken to avoid raising unhandled errors as a
* result of handling unhandled errors, since that will result in the obvious chaos.
*/
protected def reportFailure(err: Throwable): IO[Unit] =
Console[IO].printStackTrace(err)

reportFailure is specifically for "unhandled" errors. An unhandled error is an error that is raised on a Fiber that nobody is joining.

For example:

import scala.concurrent.duration._

override def run: IO[Unit] = IO(throw new Exception("")).start *> IO.sleep(1.second)

In this case, the exception is raised on a Fiber with no listeners. So nobody would be notified about that error. Therefore it is unhandled, and it goes through the reportFailure mechanism.


An error raised in run is considered to be "handled" because it is being raised directly to your application's main. If you want to handle errors that are raised in run, use handleErrorWith or similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants