3 ms·
Low-level and high-level error handling can coexist. It's no different than having a specialized try/catch inside a larger try/catch. You may, for example, cho
by piaste 3y ago
Low-level and high-level error handling can coexist. It's no different than having a specialized try/catch inside a larger try/catch.
You may, for example, choose to handle very fast transient errors inside your `send-email` function. If you manage to connect in under $acceptable-time, return to the happy path*, otherwise return to the caller.
The only hard and fast rule is that any handling requiring human intervention should definitely be wrapped up and passed up.
* but do log a warning, regardless of whether you're just doing classic impure logging, collecting the logs as part of the success value, or using a writer monad.
- ilyt 3y agovisually the classical try-catch makes error handling right there more verbose and less readable. I far prefer Rust-like passing result with maybe adding context to the error along the way than try-catch block at every step of long process that have errors that should be handled in-place. Because passing it up is still easy, but adding any context is much less verbose. > The only hard and fast rule is that any handling requiring human intervention should definitely be wrapped up and passed up. The "wrapped up" being the important and mostly ignored part. From my experience try-catch error handling usually generates incomprehensible errors where you can only guesstimate what actually happened from stack trace's function names. To get good error message every layer should have try-catch block that adds context to the error (what operation did it, or what logged user did it etc.), but that's almost never done properly and we get stack trace vomits instead. If you want it to be fixed by actual humans you need to