Earlier quoted context omitted.
To be fair, throw is GOTO. Catch() is COMEFROM :).
Technically, `throw` is `goto somewhere`.
Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
151–160 of 204 posts
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#152Error handling has been wrong since the beginning, and has continued to be wrong ever since. First, we had error codes. Except these were wrong because people forget all the time to check them. Then we had exceptions, which solved the problem of people forgetting to check by crashing the app. Then the Java team got the bright idea to have checked exceptions, which at first helped to mitigate crashes from uncaught exc…
Are you familiar with Zig's error handling? Except for the fact that errors cannot contain payloads, it is, imo, perfect.
While it would be cool to get an error payload, I would hope that if that was added to the language, that it doesn't affect the current ergonomics of error handling.
Where I've really needed to get some data back out, I've passed in a pointer to a struct that gets populated.
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#153Earlier quoted context omitted.
> Contrast that with Java, where any uncaught or logged exception prints a detailed stack trace and (usually) one or more useful error messages, by default, since day one. I think you're misunderstanding what the OP is trying to show here. If all you want is a backtrace, then Rust supports that out of the box. Here's an approximation of the full error message that you would see from the first example in the post: thr…
In other compiled languages, stack traces can be supported by looking up code references on the stack in a map of executable addresses to source code locations. Even in the absence of stack frames, the mere contents of the stack with lookups where possible is really useful, and usually more than enough. The cost is a little code to do lookups at runtime, and making the mapping data available (typically compressed and…
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#154The rule of thumb for me is `thiserror` for libraries, `anyhow` for executables. Seems to work well enough in the vast majority of cases. I do agree that the Rust way can be frustrating at first. But then, at some point it becomes clear that being forced to keep your error conditions in mind at all times is actually a healthy thing. Then going back to languages where code may fail anywhere seems less than optimal. So…
Why not `thiserror` for executables as well? It happened to me a few times that I started to write an executable program, but then realized I want to embed its functionality in a library. Converting from `anyhow` to `thiserror` at that stage would be extra work that can be avoided.
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#155Earlier quoted context omitted.
The only system I think should completely go is Exceptions except in the case of termination or absolutely catastrophic failure - this isn't really about programming but rather that the implementation is a total pain, the compiler struggles to optimize them, and even better they make quite a few safety analyses like borrow checking very difficult because the control flow graph basically explodes when you start consid…
In terms of control flow, this: try { someCall(); } catch (ErrorICanHandle err) { //handle } perfectly equivalent to this: err = someCall(); if canHandle(err) { //do something } else { return err } I don't see why so many people think exceptions make code harder to analyze. In my opinion, it is errors themselves that make code hard to analyze, regardless of implementation strategy. The only difference between excepti…
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#156Earlier quoted context omitted.
>The main weakness of this system, imo, is that the thrower, not the caller, decides whether or not a given error must be handled, and sometimes the answer is "it depends on what the consumer is doing". So... exactly the same problem that Java's checked exceptions have?
> So... exactly the same problem that Java's checked exceptions have? Well yes, but also no because Java's checked exceptions have issues which go way beyond that. Hell I'd say this is not an issue because of the other issues. In Rust the thrower decides whether the error must be handled, but the default is "yes", and it's the overwhelmingly common decision. Panic is the exception (or multiple APIs are provided). Rus…
The correct thing here is to correctly model your Error domain and map errors you don't control to Errors that you do. In the Java Checked Exception case the Throws clause only grows because everyone is trying to ignore the errors and make somebody else handle it. I would argue that in Rust the explosion of different generic error handling mechanisms is also laziness and a desire to not handle the other half of the API's you are handling.
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#157Someday I will attempt to use some rust software from the internet without almost immediately running into a panic with some inscrutable message. Maybe that day will be a day after _f$#$@@#$_ _crashing_ stops being the easiest and most idiomatic way of handling unexpected conditions.
You can't blindly copy code in C#, Java, Javascript, Go, Python, C, or any other language either, but some of those will try very hard to hide the fact that your code isn't working.
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#158The rule of thumb for me is `thiserror` for libraries, `anyhow` for executables. Seems to work well enough in the vast majority of cases. I do agree that the Rust way can be frustrating at first. But then, at some point it becomes clear that being forced to keep your error conditions in mind at all times is actually a healthy thing. Then going back to languages where code may fail anywhere seems less than optimal. So…
Why not `thiserror` for executables as well? It happened to me a few times that I started to write an executable program, but then realized I want to embed its functionality in a library. Converting from `anyhow` to `thiserror` at that stage would be extra work that can be avoided.
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#159Error handling has been wrong since the beginning, and has continued to be wrong ever since. First, we had error codes. Except these were wrong because people forget all the time to check them. Then we had exceptions, which solved the problem of people forgetting to check by crashing the app. Then the Java team got the bright idea to have checked exceptions, which at first helped to mitigate crashes from uncaught exc…
They can also harm readability, as just about every statement can now cause an early return from a block. They also greatly complicate static analysis.
No discussion of the shortcomings of conventional exceptions would be complete without these two excellent blog posts by the great Raymond Chen:
Cleaner, more elegant, and harder to recognize https://devblogs.microsoft.com/oldnewthing/20050114-00/?p=36...
Cleaner, more elegant, and wrong https://devblogs.microsoft.com/oldnewthing/20040422-00/?p=39...
> Attempting to get the complete set of error types that any given call may raise is a fool's errand because of the halting problem it eventually invokes. Forcing people to provide such a list results in the Java problem for the same reason.
The Java problem is one of ergonomics -- unwieldy lists of exception types -- not a computability problem. What do you mean here?
Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)
#160For the mostpart, Rust error handling is okay. What really rustles my jimmies, however, is the often mandatory indentation because of a lack of an inverse "if let". I prefer to bail out of a block if a condition is NOT met, rather than execute another nested block if it IS met. Rust makes that harder than it should be. It's good code hygiene in every other language, and Rust makes it painful in places. I've even been…
I totally agree. I love Swift's guard let. It makes early returning [1] easy: guard let value = optvalue else { return // optvalue is none } There has been several proposals [2][3] to fix it in Rust but they don't seem to go anywhere. I'm using this in my own code now to unwrap or return (it looks stupid): let value = if let Some(value) = optvalue { value } else { // optvalue is none return; }; [1] https://szymonkraj…
let value = match value {
None => return,
Some(value) => value
};