How should a function report an error?

Functions can fail. I have functions that try to find a steady state of a DAE system, and that can fail. What is better:

  • to raise an exception
  • to return nothing

While this error can be fatal, it does not have to be, trying again with different parameters might help.

Extra question:
Should a linter give a warning if a function returns a value or nothing?

1 Like

On this question, I really appreciate the design of Roots.jl. Its high-level API is opinionated and throws on failure, while its lower-level API gives advanced users more control over how to handle non-convergence.

I think that is a very good pattern. A high-level function should usually be safe and explicit by default. But lower-level interfaces can expose alternative failure-handling strategies for users who really need them.

If you do choose to throw, I would also recommend using a custom exception type. That way, downstream code can still recover cleanly with try/catch when appropriate, without having to inspect error strings or catch unrelated exceptions.

So for me, it depends on the API’s abstraction level.

2 Likes

For me, nothing would be too uninformative.

Similar to Roots.jl, I also prefer for internal functions to maybe also just return the error or in some way information what/why things failed – and the high level parts to throw those.