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.