Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating a whatever error value #387

Open
jondot opened this issue Jul 12, 2023 · 7 comments
Open

Creating a whatever error value #387

jondot opened this issue Jul 12, 2023 · 7 comments

Comments

@jondot
Copy link

jondot commented Jul 12, 2023

So far the proper shorthand for creating the value (but not returning immediately) was something along:

Err(FromString::without_source(
    "msg".into(),
))

is there a shorter, nicer way?

@Enet4
Copy link
Collaborator

Enet4 commented Jul 12, 2023

I'm afraid that that would be the best you can do if you want to use snafu::Whatever. But in this case you might be better served with your own error type, with support for whatever.

#[derive(Debug, Snafu)]
enum Error {
    #[snafu(whatever, display("{message}"))]
    Generic {
        message: String,
        #[snafu(source(from(Box<dyn std::error::Error>, Some)))]
        source: Option<Box<dyn std::error::Error>>,
    },
}

You can then use the selector GenericSnafu, or create your own constructor associated function.

GenericSnafu { message: "msg" }.fail()

This supports the various integrations with whatever errors, including the whatever! macro and the extension methods whatever_context and with_whatever_context, while already serving as a baseline for making the error variants more specific in the future.

@jondot
Copy link
Author

jondot commented Jul 12, 2023

@Enet4 maybe one more question,
I'm looking for a way to create a Whatever like error, but with one more context field added,
which is, in my Error type, have 2 whatever errors. One with the message, and one with a message + extra info.
I want the whatever semantics, because I want to box the previous error generically without really caring about its type, as long as I can convert it fluently.

@Enet4
Copy link
Collaborator

Enet4 commented Jul 12, 2023

I want the whatever semantics, because I want to box the previous error generically without really caring about its type, as long as I can convert it fluently.

As far as I know, that is not whatever-specific. Any error type or variant may have a dynamic source error.

#[derive(Debug, Snafu)]
enum Error {
    #[snafu(whatever, display("{message}"))]
    Generic {
        message: String,
        #[snafu(source(from(Box<dyn std::error::Error>, Some)))]
        source: Option<Box<dyn std::error::Error>>,
    },
    #[snafu(display("Failed with code {code}: {message}"))]
    WithCode {
        message: String,
        code: i32,
        #[snafu(source(from(Box<dyn std::error::Error>, Some)))]
        source: Option<Box<dyn std::error::Error>>,
    },
}

@shepmaster
Copy link
Owner

is there a shorter, nicer way?

I can't think of any technical reason that snafu::Whatever could not add an implementation of From<String> (or &str or AsRef<str>, etc. whatever works well).

Then that would be

Whatever::from("msg")

@jondot
Copy link
Author

jondot commented Jul 12, 2023

I want the whatever semantics, because I want to box the previous error generically without really caring about its type, as long as I can convert it fluently.

As far as I know, that is not whatever-specific. Any error type or variant may have a dynamic source error.

#[derive(Debug, Snafu)]
enum Error {
    #[snafu(whatever, display("{message}"))]
    Generic {
        message: String,
        #[snafu(source(from(Box<dyn std::error::Error>, Some)))]
        source: Option<Box<dyn std::error::Error>>,
    },
    #[snafu(display("Failed with code {code}: {message}"))]
    WithCode {
        message: String,
        code: i32,
        #[snafu(source(from(Box<dyn std::error::Error>, Some)))]
        source: Option<Box<dyn std::error::Error>>,
    },
}

yes, this is exactly what I did, and I also have to have something like this in place.

For some reason I have some typing hell making it work for all the cases. Will give it another try.

@Enet4
Copy link
Collaborator

Enet4 commented Jul 12, 2023

I also have to have something like this in place.

That could bring some issues. Snafu should take care of converting the source for you. Too many calls to Into::into or From::from and the compiler might not be able to infer which intermediate types are expected to be used.

@jondot
Copy link
Author

jondot commented Jul 12, 2023

Since I also have Option:

    #[snafu(display("provider error while accessing `{}`: `{}`", path, msg))]
    ProviderSourceError {
        path: String,
        msg: String,
        #[snafu(source(from(Box<dyn std::error::Error + Send + Sync>, Some)))]
        source: Option<Box<dyn std::error::Error + Send + Sync>>,
    },

I'm getting lots of incompatibilities. I guess Option screws this up, but this is similar to what the whatever variant is using, so maybe whatever macro does some magic here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants