-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Provide a common fail mechanism #486
Comments
Currently we have a naive implementation. I'm open to extended this to be a better implementation! I do, however, want to maintain a either a degree of separation between what should be handled by the argument parser, and what should be handled in user code (i.e. currently users can use Ideas? |
I think that providing a way to terminate a command line program is a good idea. It might not belong in clap, though. I am open for discussions. Currently clap contains a way to handle argument parsing related errors. I think this works really well, and should not be touched nor expanded (Except maybe provide a way to select which error code to use on exit and internalization of the error message, but that is a different story) What I am proposing here is an Trait extending extern crate clap;
extern crate hyper;
use std::io::{Read, Write};
use std::fs::File;
use clap::{Arg, App, SubCommand, OptionExt };
use hyper::*;
fn main() {
/// clap stuff resulting in matches
let url = matches.value_of("url").unwrap()
let client = Client::new();
let mut res = client.get(url).send().unwrap_or_exit("Could not send request.");
let mut buffer = Vec::new();
res.read_to_end(&mut buffer).unwrap_or_exit("Could not read response.");
let filename = matches.value_of("filename").unwrap()
file = File::create(filename).unwrap_or_exit("Could not create output file.");
file.write_all(&buffer).unwrap_or_exit("Could not write to output file.");
} This might not seem like a big win but it saves quite a lot of code. More importantly keeps the code clean and focused. You might argue that the error message is too concise and that the exact reason of the error is not given. That is true, but I think there is a way to provide this as well. As I said, I am open for discussions and I might also implement this outside clap and see if it fits. |
Ah ok, yeah I can see the utility in this, especially in providing consistent error messages. Let me think on a way to best expose or do this. I think providing an extension to Granted I think these are all easy things to add manually, i.e. not in |
Note that this can be achieved with #641 and |
@hgrecco As of version 2.11.2, your suggestion can be implemented by users of clap: trait UnwrapOrExit<T>
where Self: Sized
{
fn unwrap_or_else<F>(self, f: F) -> T
where F: FnOnce() -> T;
fn unwrap_or_exit(self, message: &str) -> T {
let err = clap::Error::with_description(message, clap::ErrorKind::InvalidValue);
// Ther ErrorKind does not really matter, because we are only interested in exiting and
// creating a nice error message in case of failure.
self.unwrap_or_else(|| err.exit())
}
}
impl<T> UnwrapOrExit<T> for Option<T> {
fn unwrap_or_else<F>(self, f: F) -> T
where F: FnOnce() -> T
{
self.unwrap_or_else(f)
}
}
impl<T, E> UnwrapOrExit<T> for Result<T, E> {
fn unwrap_or_else<F>(self, f: F) -> T
where F: FnOnce() -> T
{
self.unwrap_or_else(|_| f())
}
} |
While contributing
cut
to redox's coreutils, I came across theOptionExt
trait of libextra. It is really nice as it provides a consistent way to exit a program when a problem occurs. Being clap a command line argument parser, I think it could be very useful if it provides such trait (and its implementation).If there is consensus that this is a desired feature, I think we can discuss a few things regarding the implementation. For example, I think it might be a good idea to have a function that accepts the exit code. Additionally I think that there should be a function that defaults to stderr.
The text was updated successfully, but these errors were encountered: