Browse Source

Nicely report API failure errors in CLI client (WIP)

timvisee 7 years ago
parent
commit
4ddfbeb4b6
6 changed files with 45 additions and 21 deletions
  1. 1 0
      Cargo.lock
  2. 1 0
      cli/Cargo.toml
  3. 4 1
      cli/src/action/download.rs
  4. 8 8
      cli/src/cmd/cmd_download.rs
  5. 8 8
      cli/src/cmd/cmd_upload.rs
  6. 23 4
      cli/src/util.rs

+ 1 - 0
Cargo.lock

@@ -331,6 +331,7 @@ version = "0.1.0"
 dependencies = [
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "clipboard 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "ffsend-api 0.1.0",
  "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pbr 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",

+ 1 - 0
cli/Cargo.toml

@@ -14,6 +14,7 @@ default = ["clipboard"]
 [dependencies]
 clap = "2.31"
 clipboard = { version = "0.4", optional = true }
+failure = "0.1"
 ffsend-api = { version = "*", path = "../api" }
 open = "1"
 pbr = "1"

+ 4 - 1
cli/src/action/download.rs

@@ -6,6 +6,7 @@ use ffsend_api::reqwest::Client;
 
 use cmd::cmd_download::CmdDownload;
 use progress::ProgressBar;
+use util::quit_error;
 
 /// A file download action.
 pub struct Download<'a> {
@@ -38,7 +39,9 @@ impl<'a> Download<'a> {
 
         // Execute an download action
         // TODO: do not unwrap, but return an error
-        ApiDownload::new(&file).invoke(&client, bar).unwrap();
+        if let Err(err) = ApiDownload::new(&file).invoke(&client, bar) {
+            quit_error(err);
+        }
 
         // TODO: open the file, or it's location
         // TODO: copy the file location

+ 8 - 8
cli/src/cmd/cmd_download.rs

@@ -2,7 +2,7 @@ use ffsend_api::url::{ParseError, Url};
 
 use super::clap::{App, Arg, ArgMatches, SubCommand};
 
-use util::quit_error;
+use util::quit_error_msg;
 
 /// The download command.
 pub struct CmdDownload<'a> {
@@ -47,18 +47,18 @@ impl<'a: 'b, 'b> CmdDownload<'a> {
         match Url::parse(url) {
             Ok(url) => url,
             Err(ParseError::EmptyHost) =>
-                quit_error("emtpy host given"),
+                quit_error_msg("emtpy host given"),
             Err(ParseError::InvalidPort) =>
-                quit_error("invalid host port"),
+                quit_error_msg("invalid host port"),
             Err(ParseError::InvalidIpv4Address) =>
-                quit_error("invalid IPv4 address in host"),
+                quit_error_msg("invalid IPv4 address in host"),
             Err(ParseError::InvalidIpv6Address) =>
-                quit_error("invalid IPv6 address in host"),
+                quit_error_msg("invalid IPv6 address in host"),
             Err(ParseError::InvalidDomainCharacter) =>
-                quit_error("host domains contains an invalid character"),
+                quit_error_msg("host domains contains an invalid character"),
             Err(ParseError::RelativeUrlWithoutBase) =>
-                quit_error("host domain doesn't contain a host"),
-            _ => quit_error("the given host is invalid"),
+                quit_error_msg("host domain doesn't contain a host"),
+            _ => quit_error_msg("the given host is invalid"),
         }
     }
 }

+ 8 - 8
cli/src/cmd/cmd_upload.rs

@@ -3,7 +3,7 @@ use ffsend_api::url::{ParseError, Url};
 use super::clap::{App, Arg, ArgMatches, SubCommand};
 
 use app::SEND_DEF_HOST;
-use util::quit_error;
+use util::quit_error_msg;
 
 /// The upload command.
 pub struct CmdUpload<'a> {
@@ -72,18 +72,18 @@ impl<'a: 'b, 'b> CmdUpload<'a> {
         match Url::parse(host) {
             Ok(url) => url,
             Err(ParseError::EmptyHost) =>
-                quit_error("emtpy host given"),
+                quit_error_msg("emtpy host given"),
             Err(ParseError::InvalidPort) =>
-                quit_error("invalid host port"),
+                quit_error_msg("invalid host port"),
             Err(ParseError::InvalidIpv4Address) =>
-                quit_error("invalid IPv4 address in host"),
+                quit_error_msg("invalid IPv4 address in host"),
             Err(ParseError::InvalidIpv6Address) =>
-                quit_error("invalid IPv6 address in host"),
+                quit_error_msg("invalid IPv6 address in host"),
             Err(ParseError::InvalidDomainCharacter) =>
-                quit_error("host domains contains an invalid character"),
+                quit_error_msg("host domains contains an invalid character"),
             Err(ParseError::RelativeUrlWithoutBase) =>
-                quit_error("host domain doesn't contain a host"),
-            _ => quit_error("the given host is invalid"),
+                quit_error_msg("host domain doesn't contain a host"),
+            _ => quit_error_msg("the given host is invalid"),
         }
     }
 

+ 23 - 4
cli/src/util.rs

@@ -1,21 +1,40 @@
 #[cfg(feature = "clipboard")]
 extern crate clipboard;
+extern crate failure;
 extern crate open;
 
 #[cfg(feature = "clipboard")]
-use std::error::Error;
+use std::error::Error as StdError;
+use std::fmt::{Debug, Display};
 use std::io::Error as IoError;
 use std::process::{exit, ExitStatus};
 
 #[cfg(feature = "clipboard")]
 use self::clipboard::{ClipboardContext, ClipboardProvider};
+use self::failure::{Fail};
 use ffsend_api::url::Url;
 
+/// Quit the application with an error code,
+/// and print the given error.
+pub fn quit_error<E: Fail>(err: E) -> ! {
+    // Print the error message
+    eprintln!("error: {}", err);
+
+    // Quit
+    exit(1);
+}
+
 /// Quit the application with an error code,
 /// and print the given error message.
-pub fn quit_error<S: AsRef<str>>(err: S) -> ! {
+pub fn quit_error_msg<S>(err: S) -> !
+    where
+        S: AsRef<str> + Display + Debug + Sync + Send + 'static
+{
+    // TODO: forward the error the `quit_error` here
+    // quit_error(failure::err_msg(err));
+
     // Print the error message
-    eprintln!("error: {}", err.as_ref());
+    eprintln!("error: {}", err);
 
     // Quit
     exit(1);
@@ -35,7 +54,7 @@ pub fn open_path(path: &str) -> Result<ExitStatus, IoError> {
 
 /// Set the clipboard of the user to the given `content` string.
 #[cfg(feature = "clipboard")]
-pub fn set_clipboard(content: String) -> Result<(), Box<Error>> {
+pub fn set_clipboard(content: String) -> Result<(), Box<StdError>> {
     let mut context: ClipboardContext = ClipboardProvider::new()?;
     context.set_contents(content)
 }