You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With Rust 1.61.0 out, the Termination trait and associated ExitCode are now stable. In the past, I maintained a large error enum purely to decipher what error code to return, printed out the error using eprintln!, and then exited with std::process::exit.
Now, I'm thinking through a way for me to switch over to anyhow because it would streamline so much in my application, but I still need some way to keep track of what exit code to return for different errors. Looking for any advice/thoughts on how I could capture/encode that information when bubbling up errors.
Implement a wrapper type for anyhow::Error at the end
One way would be to create a newtype wrapper for the error and then use downcasting to figure out the underlying error with an associated exit code.
use std::process::{ExitCode,Termination};// Assume that this type implements:// 1. Display that yields the context// 2. std::error::ErrorstructExitCodeError{error:Box<dyn std::error::Error + Send + Sync>,exit_code:ExitCode,}structAppResult(anyhow::Result<()>);implTerminationforAppResult{fnreport(self) -> ExitCode{matchself{Ok(_) => ExitCode::SUCCESS,Err(x) => {ifletSome(x) = self.downcast::<ExitCodeError>(){
x.exit_code}else{ExitCode::FAILURE}}}}}fnmain() -> AppResult{AppResult(real_main())}fnreal_main() -> anyhow::Result<()>{// ...// For each error, we have to wrap the error in our ExitCodeError first if we want a unique exit code// This seems really verbose still, so maybe there's a way to simplifylet value = do_something().map_err(|error| ExitCodeError{error:Box::new(error),exit_code:ExitCode::from(22)})?;// ...}
Some cleaner way?
Ideally, I'd love something like
use std::process::ExitCode;fnmain() -> anyhow::Result<()>{
std::fs::read("some/path").exit_context(ExitCode::from(22),"Failed with specific context")?;// ...}
The text was updated successfully, but these errors were encountered:
chipsenkbeil
changed the title
Recommendation on mixing error codes with anyhow
Recommendation on mixing exit codes with anyhow
Jul 25, 2022
To bring in a specific use case; some (most?) crond implementations support the use of EAGAIN as an exit code to trigger a retry.
I am currently running into an issue with software where it would be incredibly useful to tag certain error types created with thiserror as being transient errors which can be retried and have the others be permanent errors.
A similar thing could be achieved by using Result<Termination> as in the example provided by OP where I have another layer of main and wrap handle this in an elaborate match statement, but having this integrated in either anyhow would be nice, and it would be even better if it was implemented in a way that thiserror could integrate with.
With Rust 1.61.0 out, the
Termination
trait and associatedExitCode
are now stable. In the past, I maintained a large error enum purely to decipher what error code to return, printed out the error usingeprintln!
, and then exited withstd::process::exit
.Now, I'm thinking through a way for me to switch over to anyhow because it would streamline so much in my application, but I still need some way to keep track of what exit code to return for different errors. Looking for any advice/thoughts on how I could capture/encode that information when bubbling up errors.
Implement a wrapper type for
anyhow::Error
at the endOne way would be to create a newtype wrapper for the error and then use downcasting to figure out the underlying error with an associated exit code.
Derive an error type with an exit code
Some cleaner way?
Ideally, I'd love something like
The text was updated successfully, but these errors were encountered: