5 ms·
This crate is nice to have for debugging. Thank you for writing it. I just had the case already over the past decades where everyone wants to turn every error
by dannymi 3y ago
This crate is nice to have for debugging. Thank you for writing it.
I just had the case already over the past decades where everyone wants to turn every error into Java backtraces (even when not in Java ;) ) and want to emphasize that this is almost never what one should do in regular operation.
As you said, unwrap() and expect() and panic!() do that for the "definitely a bug" case already. And, there, it's correct.
>probably most times want to let the "user" (the developer using the library) decide what course of action to take, based on the error.
I agree.
>But maybe the user wants to file a bug report, and then it would be helpful to know the file and line information.
In my opinion this belongs in the debug information (i.e. dwarf or similar) then. You can also store dwarf debug info outside of the object file.
>> What about all the other places where everything went right? Wanna log those, too? :)
>If everything went right, the Ok(val) is simply returned as Ok(val) unchanged, see `wherr/src/lib.rs`: match result { Ok(val) => Ok(val), ...
I see. But what I meant is that if the Err case of a regular Result value is enriched like this, why not the Ok case? After all, the programmer (user of your crate) could have erroneously returned Ok where they should have returned Err. Would only be consistent.
I know that that isn't easily possible there. That brings me back to "all result::Result construction sites should show up in dwarf debug info".
I use debuggers less than I should. But thinking about it that's silly. We should be able to use debuggers to debug problems, including problems like this.
- dannymi 3y agoOpen bug report about inability to set a breakpoint on Err: https://github.com/rust-lang/rust/issues/54144 https://github.com/rust-lang/rust/issues/54144
- simiones 3y agoIt seems that you are trying to take the position that Ok/Err are similar to if/else in that neither is more or less expected than the other. The very names chosen in Rust show that this is not how most think about these two cases. Returning Err is for cases that the developer considered errors, abnormal situations. This attitude that the happy-case and the error-case paths are equivalent and should be treated the same is bizarre and seems to be contradicted by virtually every language choice, even in communities that profess it. Go is probably the most notorious example of professing "errors are just regular values" and refusing to add any error-handling constructs to the language; and yet, even in Go, errors are called, well, `error`s and there are explicit patterns that everyone follows that would never be considered acceptable for regular values (such as naming all error values "err" and reusing the "err" variable to hold any error returned by any function in the same context - try that with a "ret" to hold any non-err return value and see how many people accept your code).
- segfaltnh 3y agoBut errors that are returned by functions are expected behavior. Except for where you assert its bizarre you seem to support this position. The only semantic thing rust offers here is '?', and that's just syntax sugar for errors are values. Truly exceptional situations are those we don't expect, and for that we panic. I expect errors, because it's a computer and that's what they do.
- simiones 3y agoNo, the error path is a distinct concept from the success path, in almost all situations. The success path implements some kind of business logic, and will be highly specific to the task at hand. The error path almost always does nothing more than returning early with an indication that the operation failed (with some context about the failure) to an entity above, ultimately to the user. A minority of cases may involve an automatic retry of the operation. Anything else is vanishingly rare. As such, virtually all languages separate the business logic from the error logic. They offer exceptions, or Rust's ? macro, or enshrine certain error handling patterns (negative return codes in C, if err != nil in Go, use of the Either monad in Haskell).