2 ms·
I disagree -- the determinant is about state management and locality of error handling and this is all about how your code is structured, not whether the error
by KayEss 11y ago
I disagree -- the determinant is about state management and locality of error handling and this is all about how your code is structured, not whether the error is expected or not in some nebulous sense.
If you can handle the connect failure locally (i.e. probably no further away then caller of the connect function) then by all means do so. If you find another structure in your code makes other things simpler, but no longer allows you locality of error handling you should use an exception.
Well designed libraries allow you to choose. Check out Boost.ASIO for an example of this. Every API has both an exception and error handling version and you're free to use whichever is most appropriate for what you're trying to achieve.
This whole thing about 'expected' and 'unexpected' errors is a red herring that leads people down the wrong path.
The exception backs you out of the transaction that your code is performing -- this is the way to think about it. An error code allows you to try something else whilst keeping the transaction alive. Which you use depends not at all on whether you think the error is "normal" or not.
- bjourne 11y agoWell, the reason exceptions should be reserved for exceptional cases is because they are gotos. There is no way around that, a function that both returns values and throws exceptions is more complex than one that doesn't because you are jumping through call frames. I once worked with a billing system that threw a BillingException when a charge didn't go through. It works ok, as long as your only response to such an error is to spew an error message to the user. But the more you need to handle it, the less an exception makes sense. The code that tried to handle the BillingException was a tangled mess of try and catch statemetns mixed with retry loops. For example, if there was a temporary error at the payment provider, you would just retry a few times, a permanent error, try with another account, if the customers remaining funds were to low show an error message or if they were just a few dollars of, charge them that and be happy we got something from them. On the other hand, the billing system could also throw a DbException in case there was something wrong with the database connection. That's a different kind of problem and fatal for a database-backed website. Nothing to do, except log the error and crash. The point of exceptions is not so much that you can catch and handle them, but that it separates exceptional situations from in-band normal error handling. Now what is in-band and what is exceptional depends on the circumstances which is why, as you say, Boost.ASIO provides both variants. If your system is supposed to handle the errors, use the one without exceptions. If not then use the one with exceptions.
- KayEss 11y ago> separates exceptional situations from in-band normal error handling Of course if you redefine "exceptional" to mean out of band error handling then we're in perfect agreement :) I've also written billing systems and the worst possible thing that happens is that you get stuck on a single customer due to some unforeseen circumstances and can't go on to bill others. The ability to abort the in-code transaction for that customer and move on to the next is exactly what you want from the system, and the exception there makes that a far simpler thing to do (together with RAII for clean up). > function that both returns values and throws exceptions is more complex Indeed, but it doesn't really matter because the clean up you get from exceptions with RAII means that the correctness of the function is easier to reason about and that's what you really care about.