3 ms·
Two of the fundamental principles of object-oriented programming are encapsulation and polymorphism; the idea that exceptional errors are part of the API contra
by wvenable 9y ago
Two of the fundamental principles of object-oriented programming are encapsulation and polymorphism; the idea that exceptional errors are part of the API contract is completely at odds with idea of isolating the implementation of different components.
A component that calculates exchange rates might use a file today and a network service tomorrow. My code should not have to care how every single component is implemented all the way down through the entire code base and every 3rd party library. And if my code is designed to restart high-level operations due to temporary network exceptions then it will be robust without knowing which components use the network now or in the future.
Properly typed `result` types and checked exceptions make implementation details explicit. I don't want that part of the API contract.
- cesarb 9y agoWhat matters is whether the component is _fallible_ or not. If a component can fail, its caller has to be able to deal with the failure, even if it deals with the failure by also failing (propagating the failure). Your example already could fail (on a missing file today, on a network problem tomorrow), so a well-designed API contract (which doesn't unnecessarily expose the _cause_ of the failure) wouldn't have to change. The implementation detail is the cause of the failure, not the fact that it can fail.
- wvenable 9y agoAll components can fail; even if just by programmer error. There is a difference between expected failures and unexpected failures. I like to use the example of int.Parse() and int.TryParse() in C#. These functions do exactly the same thing but treat errors very differently. You use int.Parse() when you expect the parse to always succeed. It will raise an exception if the parse fails. int.TryParse() doesn't raise an exception, it returns a boolean and you use it when you expect the parse to fail. Returning a boolean indicating success/failure can be part of the API contract with well defined semantics. But that can't help you with unexpected errors that are part of the implementation. For unexpected failures, you want to know the cause of it and you want as much implementation detail as possible. I can't recover from a missing file, but I can recover from temporary network problems. If the file is missing, I want to know what file is missing so I can fix that manually.