3 ms·
One of the issues in Go is that if all you ever do if "if err != nil { return err }", you will quickly run in to problems because you will have errors like "ope
by arp242 2y ago
One of the issues in Go is that if all you ever do if "if err != nil { return err }", you will quickly run in to problems because you will have errors like "open foo: no such file or directory" or "sql: no rows in result set" without a clue where that error came from. Sometimes that's obvious, often it's not.
I'm not sure how Rust handles that? But it's more than just "propagate errors", but more like "propagate errors with the appropriate context for this specific error".
- bbatha 2y agoRust uses the `?` operator to convert between error types which allows for users and libraries to hook in to the error before its returned. There are a number of helper libraries that provide an extended type erased error type to attach a real stack trace to the error, such as `anyhow`. These helper libraries also provide ways to attach extra metadata to the error so you can do things like `returns_a_result().context("couldn't do it")?` so you can quickly annotate the error. The standard library is support for this through a `context.Value` like api on the Error trait. The std lib `Error` trait also has functions for find the cause of the error and traverse a collected chain of errors, very similar to go's `errors.Cause` api. Rust also has a number of libraries for making specific error types like `thiserror` which can help generate error enums with the implementations required to carry backtraces, context and causes.
- kbolino 2y agoYep, if you want wrapped errors in Rust, you use the anyhow crate. It leans heavily into dyn so has some performance tradeoffs, but it's roughly the same performance-wise as Go's error interface (which also uses a vtable under the hood).
- kibwen 2y agoThough using a dynamic error in Rust should only impose an allocation cost on the error path, and I presume Go is the same.