Related - [[Error Handling in Programming Languages]] [wikipedia](https://en.wikipedia.org/wiki/Exception_handling) Exception is an interesting construct; Depending on which programming community you are part of, you'll either utilize them or denounce them. First, there's exception from the computer science and general programming language perspective. Exception - computer science * control flow constructs that you can raise and catch it. Exception - software engineering * stack traces * exception type hierarchy # History * Started off with Lisp * Initially, exceptions had two semantics - Termination and Resumption. Over time, the industry converged to the terminating semantic (resumption semantic is better handled via [[Coroutine]]s) # Examples Good case - Java / Python * Heavily used * Java has *Checked Exceptions* which ... is a good idea that is painful in practice. Bad case - C++ * Constructor / Destructors and exceptions didn't get along. https://learn.microsoft.com/en-us/cpp/cpp/errors-and-exception-handling-modern-cpp?view=msvc-170 Awkward case - [[JavaScript]] * Similar to C++, Callbacks and exceptions didn't go along; * Lack of typed catch statement made exceptions very difficult. Banned case - [[Go]] * `defer` * `panic` * However, [[Go - Errors]] evolved to have more exception like characteristics - namely: * Error Chaining * Stack Traces * Typed Catch (via `errors.Is` and `errors.As`) # Why Exception is good Exception allows you to write haphazard code and wrap it in try-catch. In the modern the software engineering, this is *immensely popular*. ```java try { renderSubPane(); } catch (Exception e) { reportError(e); // ex: sentry.io renderErrorPane(e); } ``` For server-side programming with good iteration cycle, this style of programming works *really well*. # Why Exceptions are bad * Nested Finally statements * RAII # Observations * If one is acting on the exception, then incorporating it into the return type instead of exception is desirable. * Java has checked exceptions, which *seems* like a good idea; in reality; it's the worst of the both worlds. ```java try { a(); b(); c(); } catch (Exception e) { // not clear whether a, b, or c triggered this. } ``` * Technically, stack traces contain the method information (that's why exceptions are powerful debugging tools). However; **One should not use this for control flow purposes**. * Try-finally is more useful than Try-catch * This speaks to RAII being one of the most valuable concept. * Go has `defer` statements, which is akin to `try-finally` * Type System is needed. * Technically, exception doesn't entail any typing information. * JavaScript allows any arbitrary object to be thrown; Same as C++ though inheriting from `std::exception` is heavily recommended. Python2 allowed this too - *exceptions must be old-style classes or derived from BaseException* * common exception base type allows for functionalities such as exception chaining and stack traces - features we commonly associate with exceptions. * Catch statement without types - is not very useful; Even in an exception endorsing languages like Python/Java, generic `catch (Exception e)` (or even worse, `catch (Throwable t)`) is heavily discouraged unless you're at the outermost layer of a framework. One wants to be surgical about exception catching, and without typed catch support, one needs to have an ad-hoc implementation to introspect the exception and raise it again when the exception is not what you're looking for.