I much prefer the explicit error returns instead of exceptions being used for flow control.
A loud exception is way better.
The Python community, by and large, embraces "easier to ask forgiveness than permission" and some features in the standard library use exceptions for their flow control. It's much more likely to run into overuse of exceptions in Python than not.
What signature do you get from "if err := myFunction()"?
It's still just a generic error object, possibly a string. You still have to write a handler for it. Why do it every time?
I have a web application. There is a SQL query that produced no results for an object. I throw an ObjectNotFoundException. It results in an HTTP 404, producing a web page or a JSON response, depending on the request location, and I handle it all once.
You provided an example from Go which is almost like an exception. And I think it is bad. You have a function that returns....something?? Instead, if you have something like Result<T,E>, it tells you exactly what you're getting.
```
value = myFunction();
match value {
Ok(v) => // whatever
Err(MalformedSQL) => // oh something with sql happened?
Err(UserNotFound) => // oh can't find user?
```
Then you get "BZZZZZ, compile error. You forgot to check for another variant of the Error (ThirdPartyLibraryError)" which is a million time better than catch-all exception handling because you are afraid something might get out of this function call. If you do want to have a catch-all exception handling, then that is also possible by using "_ => {}" which is explicit. So just glancing at a piece of code, you know you have handled ALL the possible error cases.
>I have a web application. There is a SQL query that produced no results for an object. I throw an ObjectNotFoundException. It results in an HTTP 404, producing a web page or a JSON response, depending on the request location, and I handle it all once.
Also possible in axum. You have an error enum and then you implement a trait that converts said enum into an HTTP response. So your code looks something like
```
value = myFunction()?;
```
and if there's any error it will automagically turned into the appropriate response. So I get all the ease of exception but the type signature is not lying to me. If I forgot to implement a conversion from some new error to HTTP I get compile time error.
So far, the only programming environment I've seen that makes a three-way distinction between raising, recovering, and deciding how to recover from an error is Common Lisp with its condition system[1]. However, I've successfully implemented the idea in Java using exceptions as the non-local control flow primitive, and in C using setjmp/longjmp.
[1]: https://lispcookbook.github.io/cl-cookbook/error_handling.ht...
I'm not sure I follow the distinction here, or at least why it would be important? i.e. if I parse "decide how to handle the error" as catching the exception, where I handle it is surely basically anywhere since I'm not restricted in calling into other code to do so.
Oh, you have to manually chain your errors and no you don't get stack traces out of the box. If you want to to know where the error message is, I don't know, guess?
It's insane.
Exceptions happened precisely because manual error-handling was messy and did not scale, but suddenly it's The Way.