Is error-throwing bad functional programming?

There are usually two kinds of runtime errors - ones that you can recover from, and others that you cannot recover from. Irrespective of whether or not you can recover from an error, the path from error-discovery to error-reporting is what determines what degree of flexibility you may need to handle the error. In a web application, when you cannot connect to the database you can either simply return HTTP 500 or (for example) fallback to reading stale data from from a cache. Similarly, when you have an input error you can either straightaway return HTTP 400 or (for example) try to find typos in the input based on Levenshtein distance and try to construct a more helpful error message.

For most simple cases, where it is straightforward to turn discovered error into error message, you can probably use a generic handler (probably as a Ring middleware) to translate exceptions into error messages. However, when error-discovery leads to several post-discovery steps you probably need more powerful error handling. In such scenarios you may need to express error as data in order to have flexibility and composability during error processing.

Whether exceptions are enough or you need to express error as data really depends on your taste and your needs. In my experience, complex error handling with exceptions has led to unwieldy pattern matching and imperative code. On the other hand, expressing error as data has let me operate at a higher level of understanding about how to handle various scenarios.

Full disclosure: I’m the author of Promenade; my bias may be obvious. :slight_smile:

6 Likes