Open epage opened 3 years ago
Some ideas:
The generic member access RFC makes it so we can extract exit codes from arbitrary errors if they provide one. If we updated std::process::ExitCode
to be able to represent all the exit codes we could return or use with std::process::exit
then we could update the Termination
implementation on Result
to attempt to pull an ExitStatus
from the chain of errors (probably requires specialization here, questionable if possible).
Something like this:
#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl<E: std::error::Error> Termination for Result<!, E> {
fn report(self) -> i32 {
let Err(err) = self;
eprintln!("Error: {:?}", err);
let exit_code = err.context::<&ExitCode>().unwrap_or(&ExitCode::FAILURE);
exit_code.report()
}
}
Even if we don't update the std ExitCode
and Termination
impls, once Termination
is stable people will be able to introduce their own Result
equivalent at the top level that has the proper implementation for grabbing exit statuses of any type, even defined by third party libraries, from any type that implements the Error trait, which might be sufficient.
Until Termination
is stable people can still use the same approach proc-exit
does, and that library could change the interface of exit
from fn(ExitResult) -> !
to fn(Result<(), E: Error> -> !)
and still manage to find all of its own Code
's via the generic member access interface, letting errors with exit codes associated compose nicely with other error types.
I suggested up #20 largely because it'd make rust's handling of numeric exit codes far more POSIX like but more flexible.
If created from a a numeric error code, then a TinyBox<dyn TinyError>
would be [usize; 2]
with no allocations. It'd even work without the alloc crate, but still track dynamically the error's original type, and support some downcast methods.
It could then later be promoted to allocation based types that track the backtrace, etc., maybe one could even make this promotion depend upon a alloc feature, but the point is largely to make smaller rust crates more usable when doing things like writing an OS.
I actually noticed that #20 would be useful from seeing zcash's crypto libs use the Read
and Write
traits for serializations. At this point, arworks/zexe has their own fork of those traits, but it'd still be cool more std::io tooling just worked without std or alloc.
I suggested up #20 largely because it'd make rust's handling of numeric exit codes far more POSIX like but more flexible.
Makes sense and good to know
If created from a a numeric error code, then a TinyBox
would be [usize; 2] with no allocations.
fwiw, I think this is also true of ZST
error types plus Box
, tho im pretty sure you'd still need an alloc dependency even if it doesn't allocate a real pointer.
fwiw, I think this is also true of ZST error types plus Box, tho im pretty sure you'd still need an alloc dependency even if it doesn't allocate a real pointer.
The idea is the tinybox crate would have an alloc feature. If the alloc feature is enabled then it invokes box for types with alignment or size larger than usize
. If the alloc feature is disabled, then tinybox panics for types with alignment or size larger than usize
, meaning it still builds but pushes the error into runtime. If a type has alignment and size no larger than usize
then tinybox always works with or without the alloc feature.
There are two sides to this
Turning
std::process::Command
into errorsProviding a way to bubble up process exit codes to main
std::process::Command
s exit code to bubble up, sometimes they won'tstd::io::ErrorKind
to bubble up and sometimes they won'tAlternative:
std::process::exit
throughout the business logic. Personally, I've found unexpected forms of exiting a program to lead to "spaghetti code".Exit code prior art:
std::process::ExitCode
sysexit
std::process::Command
s andstd::io::ErrorKind
s to codesexit-code
andexitcode
i32
constantsproc-exit
std::process::Command
s andstd::io::ErrorKind
s to codesmain
prior art:std::process::Termination
Debug
intoDisplay
forTermination
traitproc-exit
Debug
intoDisplay
if choosing to rely onTermination
traitTermination
, provides a way to get custom exit codes to the user