(In fact, it leaves my favourite solution out: using the derive_more crate to auto-generate From implementations for the ? operator to use. From is a general trait, useful for far more than error handling, which is probably why it's omitted here.)
(In fact, it leaves my favourite solution out: using the derive_more crate to auto-generate From implementations for the ? operator to use. From is a general trait, useful for far more than error handling, which is probably why it's omitted here.)
And the variety exists, because there are different needs and trade-offs:
• You may want an error type that takes 0 bytes, so that `Result` is cheap for trivial high-performance functions (e.g. parsing libraries that may fail on every byte).
• You may want your error type specify exact cause of failure in your library in a programmatic way, so that callers can turn it into a precise, localized error message for the end user.
• You may want to have a super rich detailed error object with all the context, e.g. an entire HTTP response for a 5xx status.
• And some application developers prefer having an "I don't care, just give me the backtrace" error wrapper for everything, to speed up the development and not spend time on micro-managing error types.
All of this works nicely and uniformly in `Result<Ok, Err>` with some `Err` type written (or generated) by you.
That's me tbh. I actually love Rust's error story atm, I always use an Error enum and I have made it do everything I want.. except one thing: Low (no?) cost backtraces.
My error enums give me all the API-level specifics I want, but often I make the variants grouped by general code area. It's guided by my program flow, not debug introspection. So if I don't need to branch a codepath from an error object, it typically just goes into a single variant and I shove some message in there.
What I'd love is to be able to easily and quickly just bake backtraces into this "non-program flow defining type". Bonus points if it could be done at compile time.
I've thought about using a macro at error creation time to make it a compile-time poor mans backtrace, but I'm unsure if just one level of stack trace is all that beneficial.
Either way I know I want something that's no more costly than:
foreign_err.map(|foreign_err| MyError::Dump(format!("some description: {}", foreign_err)))
edit: I should add, internally my perspective is coming from Go, so wrapping repeatedly in strings is fairly welcome to me. Just adding some low-cost default context to this would be a huge help.Crates like my SNAFU (https://docs.rs/snafu/0.6.0/snafu/) help abstract this away. Whenever the standard library implementation stabilizes, you will likely see many more errors including backtraces.
I fear bubbling an error up and repeatedly adding a stack trace or some junk like that. Admittedly I have not looked too much into Backtrace, but I hope my concern makes sense.
SNAFU addresses this by allowing `Option<Backtrace>` in the error struct. The backtrace is only captured when an environment variable is set by the end user.
Checks the username of who you responded too: I'll blindly bet yes to that question for any amount you desire.
It's usually not much more code than I would have written with an error handling library and it's fully transparent, understandable for anyone with a rudimentary understanding of Rust. And I get to have one less dependency.
It's certainly less transparent, but I prefer this method of error handling, and writing out the Impls manually can get out of hand (as well as having to adding new fields to the enum).
People are using rust as they do other general purpose programming languages that have somewhat of a focus on systems programming: to write code. Your question isn't really easy to answer in the same way that someone asking "what are people building with python?" isn't useful. The answer is everything from webpages to text editors to operating systems, and everything in between.
I use it for all my personal projects as well. Which are basically the same types of things I wrote in Go. Though, I also am experimenting with WASM DOM UIs, something I've not yet used in Go.
I have a feeling that inside of 5 years Rust will be blowing up on the job market. It's just so good and so practical that once you pick it up, anything less well designed will feel like a kludge and hack that might blow up on you at any point.
My current pet project in Rust is writing a functional language compiler that compiles down to System F/F omega and eventually I'm going to build some kind of virtual machine
E.g. I have written a cache-warmer that preopens and does readaheads (posix_fadvise) for assets from NFS and offers the already open file descriptors to the calling process. The NFS share offers decent throughput but terrible latency (compared to NVMe). Opening files is slow, walking directories sequentially is slow. And then hitting cold pages is slow. Doing all this in rust and handing the file descriptors over to node lets me reduce minutes to seconds. But if someone doesn't like it, there's a flag that turns it all off, back to the slow path.
Another use is essentially replacing shell-scripting when some REST APIs, JSON parsing and so on are involved. E.g. to glue together some status reporting in CI. There are so many different unreliable APIs without client libs involved that I appreciate the error handling.
I also have a lot of personal pet projects written in rust: an MMORPG-style game, accounting software, various WASM widgets, some OS fiddling, some work extending servo as a browser that implements umatrix-like control but lets you set options per domain (e.g. 3rd party cookie, user agent setting, etc, all per-domain).
I've also contributed a number of small libraries that I wrote for my projects to open source (textnonce, float-cmp, mailstrom, formdata, mime-multipart, solvent, ddsfile, pemmican, resolv-rs, email-format, and others).