|
|
|
|
|
by karatinversion
2027 days ago
|
|
> There's roughly two situations for error handling: near the leaf of the call tree, where you have enough context to deal with an error, and need to switch on error type and take compensating action; or near the root of the call tree, in the main loop, where you log errors and terminate requests etc. in a generic way (e.g. 500 response). There is actually a third case: in library code which calls other code which may fail. Take java.io.BufferedReader - to be usable, it has to be at a level of abstraction where it cannot deal with any errors the underlying Reader may throw; but the code using BufferedReader will have provided it with its underlying Reader, and will have a good idea of what errors are reasonable to expect from it. The reason java's checked exceptions are so bad is that they cannot (or could not, before generics, and hence in most of the standard library do not) serve this use case, leading to checked exceptions that one really can't do anything with. |
|
I think this is covered by the abstraction-breaking nature of failure modes, though. If your BufferedReader exposed the underlying Reader's failure modes, it's not just any BufferedReader any more, it's a BufferedReader<MySpecialReader>, and you don't get runtime polymorphism. You can write more generics to keep the polymorphism in static-land, but then you lose the ability to make choices based on error types.
The incompatibility is between errors and abstraction, not simply a single instance of composition.