-
Notifications
You must be signed in to change notification settings - Fork 61
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
multiple error types (struct and enum) and generic IntoError
#411
Comments
This is a big point the point of SNAFU and a major reason it was created; note how the example in the README essentially mirrors yours.
The big missing thing for me here is why? The closest case I can think of to yours is when I have an error with many detailed variants that I want to categorize into coarser groups. For this, I usually create a separate enum and then an inherent method. A common example is when reporting an error via HTTP and you want to get a status code: #[derive(Debug, Snafu)]
enum Error {
Thing1,
Thing2,
Thing3,
}
enum Status {
Http400,
Http500,
}
impl Error {
fn status(&self) -> Status {
match self {
Self::Thing1 | Self::Thing2 => Status::Http400,
Self::Thing3 => Status::Http500,
}
}
} |
oh, great, I must have read the example in the
maybe it's just a personal tastes. in my case, because the instead of repeat use git2::Error as GitError;
#[derive(Debug, Snafu)]
pub enum MyError {
BbAlreadyExists { source: GitError },
BaseIndexDirty { source: GitError },
// many other cases
WorktreeConflict { source: GitError },
} I'm more fond of the struct style: enum ErrorKind {
BbAlreadyExists,
BaseIndexDirty,
// many other cases
WorktreeConflict,
}
struct MyError {
kind: ErrorKind,
source: GitError,
} my current workaround is to use a custom extension trait for pub trait MyResultExt<T> {
fn kind_context<Kind>(self, kind: Kind) -> Result<T, Error>
where
Kind: snafu::IntoError<ErrorKind, Source = snafu::NoneError>;
}
impl<T> MyResultExt<T> for Result<T, GitError> {
fn kind_context<Kind>(self, kind: Kind) -> Result<T, Error>
where
Kind: snafu::IntoError<ErrorKind, Source = snafu::NoneError>,
{
self.context(Snafu {
kind: kind.into_error(snafu::NoneError),
})
}
} at least it solves my problem at hand.
thanks for the tips. now that I think about it, I probably don't need all those error kind variants in the first place, many of them (which I don't plan to handle, just to report to user) can be put into coarse groups indeed. I'm gonna close this for now, as it's not really a problem of an aside: I played with the |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
I encountered problem when writing a program with multiple error types. I have read #199 #399 and #406 which are slightly related but not quite the same.
the tldr
basically, I want to make the context selectors usable for different error types, given one of the types is just (kind of) a transparent wrapper of the other (with an added
source
field), e.g.long text alert:
I started with string contexts for prototyping, something like
after I got a picture of all the error conditions I might need propogate, I started to rewrite with enumerated errors:
this is much better, but I find out most of my errors have a single type as source (
std::io::Error
in above example code,git2::Error
in the actual program), so I attempt to rewrite it like this:I'm not very pleased with this, so I looked into the expanded code of derive macro, and came up with:
it works, but I have to manually handle every context selectors, once I try to make it generic, I run into conherence violation (E0210):
I think I understand the cause of the error, but I wonder if I can get some help from the upstream
snafu
crate, for example, after reading #399 (comment)_ I think that approach might suit my use case, i.e.:NoneError + Selector -> ErrorKind
,std::io::Error + Selector -> MyError
, in my case, my error types are not generic, so the compile error mentioned in the linked comments should not be an issue.PS
after writing the above, I realized my use case might be better served by the
error-stack
crate, where the source chain/stack is a separate concern than the error types themselvs. in theerror-stack
model, error types don't contain the source chain explicitly, but only contains information about current context of the relevant error, while the source chain is implicitly managed by an external wrapper type (with type erasure). the thing is, I don't like they way how they conflate errors with reports. anyway, I might give that a try.The text was updated successfully, but these errors were encountered: