Replies: 2 comments 3 replies
-
This is a good question, albeit tricky to answer. As the size of Backtrace depends on the target platform and/or on which backtrace implementation is used, it is hard to expect a universal maximum size. In my projects I have have taken a similar path of boxing error sources to comply with the default maximum size recommended by Clippy.
Having a root error is not a mandatory pattern in SNAFU. An interpretation of the Many Error Types design philosophy is that if a separation of error cases is possible, that would be preferred over centralization. |
Beta Was this translation helpful? Give feedback.
-
I've been recently going the opposite direction and making extremely fine-grained errors, down to the level of one error type per function. This allows the caller of the function to only have to deal with the exact set of errors possible. There's no need for a match arm like
And this is the (current?) tradeoff. As I see it, the ultimate problem is that Rust allows taking a reference to every type, which means that every value needs to be able to stand on its own. My gut tells me that this will ultimately require a language level solution. Off the top of my head, there's been various discussions that would help:
I think if you had to fit into a tiny size envelope today, your best bet would be to have one giant error enum. However, I wouldn't go down that path until I truly had to.
I think in general this is going to be application-dependent, but in the absence of benchmarks / profiling data, I'd probably stick to whatever Clippy warns about by default.
I'm surprised to hear that context field is causing the problem. Were I faced with this issue, I'd probably limit myself to boxing entire error values and not worry about specific fields. Depending on what details you want to expose, you could potentially make use of [opaque errors][opaque] to (maybe automatically?) perform the boxing at specific boundaries.
I basically never use a
I've spent zero time trying to optimize |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I used to work on research projects (using Rust) without careful error handling, relying heavily on
unwrap. Recently, I've been trying to adopt SNAFU and its philosophy. I enjoy the convenience of adding context and having an error enum per module. Now that I've integrated SNAFU throughout my Rust project, I've been pondering some questions, but haven't found the answers yet.With an error enum type per module, having deeply nested modules can lead to increasingly large error enums. The size issue is exacerbated by context fields like
String,PathBuf, and carrying source and backtrace. I've frequently used boxed types, such asBox<String>,Box<PathBuf>,Box<InnerError>, andBox<Option<Backtrace>>. I've managed to restrict the size of Error types per module, but it does make the definitions cluttered. I'm currently usinglarge-error-threshold = 25inclippy.tomlto warn me of large error enums. While a 24-byte Error enum with indirection (heap allocation for error/context) is great for the happy path, I've noticed that the Whatever type is fairly large (88 bytes on M1 Macs), and the Error type of rust-htslib is also not small (48 bytes). Is there a practical threshold for enum Error sizes? Above which should we consider boxing them to reduce size? Should we limit the depth of modules/error enums to control Error size growth?Currently, I've multiple Error types returned by public functions at different levels. Should we convert Errors from all APIs across different modules to a single Error type (i.e., the root enum Error)?
Beta Was this translation helpful? Give feedback.
All reactions