Description
Hi @shepmaster! Thank you for the wonderful crate!
Problem
I have been switching my project to utilize snafu
. Previously, I used anyhow::Error
as a generic error type when I didn't understand how to implement error types. Now I am rewriting my project with proper error types, and in the meantime switching out anyhow::Error
with snafu::Whatever
.
When switching, I ran into a problem. I have a future being spawned via Tokio, where the future has a output type of Result<(), snafu::Whatever>
. As this is concurrency, the rust compiler complains that that Whatever
does not have Send + Sync
markers for its source type. The compile error is pretty indirect about this issue. I have the error included at the bottom of this post. To figure out where this issue was coming from required a bunch of research, as shown below.
Research
Searching "snafu thread saftey" on Google returns the project http-whatever
, where they essentially implement a new Whatever but with Send + Sync
attached to the StdError
:
Snafu's Whatever:
Lines 1557 to 1569 in 073cc38
I found a snafu issue from January 2022 that asks for implementation details for making a custom snafu error type be async compatible. From there in May 2022 a PR was merged that showed an error type with async/multi-threading as part of the tests. This is part of the tests, but not part of the examples, so finding this example required a bunch of searching as its not part of the doc examples.
In addition, anyhow::Error
has Sync + Send
markers (source in anyhow code, source in anyhow docs).
Question
Why isn't Whatever
Send + Sync by default?
I could implement a new Whatever as done by http-whatever
and as shown in the snafu test. But, if we consider snafu::Whatever
to be a catch-all error type until the user can make more specific types, shouldn't we expect as a user that it can be used in all places including async and multi-threading? Is there a detail I am missing that makes Whatever not able to be Send + Sync compatible by default?
Thank you!
Whatever Send + Sync error report
error[E0277]: `(dyn StdError + 'static)` cannot be sent between threads safely
--> src\file\file.rs:435:88
|
435 | ... task = Some(Handle::current().spawn(async move {
| ____________________________________________________________________-----_^
| | |
| | required by a bound introduced by this call
... |
452 | | ... return Ok::<(), snafu::Whatever>(());
453 | | ... }));
| |_______________________^ `(dyn StdError + 'static)` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `(dyn StdError + 'static)`
= note: required for `Unique<(dyn StdError + 'static)>` to implement `std::marker::Send`
note: required because it appears within the type `Box<(dyn StdError + 'static)>`
--> C:\Users\zardini123\.rustup\toolchains\1.76.0-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\src\boxed.rs:195:12
|
195 | pub struct Box<
| ^^^
note: required because it appears within the type `std::option::Option<Box<(dyn StdError + 'static)>>`
--> C:\Users\zardini123\.rustup\toolchains\1.76.0-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\option.rs:570:10
|
570 | pub enum Option<T> {
| ^^^^^^
note: required because it appears within the type `Whatever`
--> C:\Users\zardini123\.cargo\registry\src\index.crates.io-6f17d22bba15001f\snafu-0.8.2\src\lib.rs:1563:12
|
1563 | pub struct Whatever {
| ^^^^^^^^
note: required because it appears within the type `Result<(), Whatever>`
--> C:\Users\zardini123\.rustup\toolchains\1.76.0-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:502:10
|
502 | pub enum Result<T, E> {
| ^^^^^^
note: required by a bound in `Handle::spawn`
--> C:\Users\zardini123\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.36.0\src\runtime\handle.rs:189:20
|
186 | pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
| ----- required by a bound in this associated function
...
189 | F::Output: Send + 'static,
| ^^^^ required by this bound in `Handle::spawn`
Activity