Require human-tagging errors
authorYehuda Katz <wycats@gmail.com>
Thu, 19 Jun 2014 17:12:51 +0000 (10:12 -0700)
committerYehuda Katz <wycats@gmail.com>
Thu, 19 Jun 2014 17:12:51 +0000 (10:12 -0700)
src/bin/cargo-git-checkout.rs
src/bin/cargo.rs
src/cargo/lib.rs
src/cargo/ops/cargo_compile.rs
src/cargo/ops/cargo_read_manifest.rs
src/cargo/ops/cargo_rustc.rs
src/cargo/sources/git/utils.rs
src/cargo/util/config.rs
src/cargo/util/errors.rs
src/cargo/util/toml.rs

index 6f3f374250eca3180cc265cfb80161025c12e1a1..326d8d6a53299ed6331cd458205a2f29b3aa108f 100644 (file)
@@ -9,7 +9,7 @@ use hammer::FlagConfig;
 use cargo::{execute_main_without_stdin};
 use cargo::core::source::{Source,SourceId};
 use cargo::sources::git::{GitSource};
-use cargo::util::{Config, CliResult, CliError, Require};
+use cargo::util::{Config, CliResult, CliError, Require, human};
 use url::Url;
 
 #[deriving(PartialEq,Clone,Decodable)]
@@ -29,7 +29,7 @@ fn execute(options: Options) -> CliResult<Option<()>> {
     let Options { url, reference, .. } = options;
 
     let url: Url = try!(from_str(url.as_slice())
-                        .require(|| format!("The URL `{}` you passed was not a valid URL", url))
+                        .require(|| human(format!("The URL `{}` you passed was not a valid URL", url)))
                         .map_err(|e| CliError::from_boxed(e, 1)));
 
     let source_id = SourceId::for_git(&url, reference.as_slice());
index 15c2762a69f57911938deb24b2f1fd75c53bd6b7..75608afbe766bd74d8c932a5e626a9d1edfa9f51 100644 (file)
@@ -13,7 +13,7 @@ use std::io::process::{Command,InheritFd,ExitStatus,ExitSignal};
 use serialize::Encodable;
 use cargo::{NoFlags,execute_main_without_stdin,handle_error};
 use cargo::util::important_paths::find_project;
-use cargo::util::{CliError, CliResult, Require, config};
+use cargo::util::{CliError, CliResult, Require, config, human};
 
 fn main() {
     execute();
@@ -67,7 +67,7 @@ fn execute() {
 
 fn process(args: Vec<String>) -> CliResult<(String, Vec<String>)> {
     let args: Vec<String> = Vec::from_slice(args.tail());
-    let head = try!(args.iter().nth(0).require(|| "No subcommand found").map_err(|err| CliError::from_boxed(err, 1))).to_str();
+    let head = try!(args.iter().nth(0).require(|| human("No subcommand found")).map_err(|err| CliError::from_boxed(err, 1))).to_str();
     let tail = Vec::from_slice(args.tail());
 
     Ok((head, tail))
@@ -133,7 +133,7 @@ fn locate_project(_: NoFlags) -> CliResult<Option<ProjectLocation>> {
     let root = try!(find_project(os::getcwd(), "Cargo.toml").map_err(|e| CliError::from_boxed(e, 1)));
 
     let string = try!(root.as_str()
-                      .require(|| "Your project path contains characters not representable in Unicode")
+                      .require(|| human("Your project path contains characters not representable in Unicode"))
                       .map_err(|e| CliError::from_boxed(e, 1)));
 
     Ok(Some(ProjectLocation { root: string.to_str() }))
index 0830956b0e48fe70b794878e47982e89141ba521..61ce7ad09d7f8693ae8a5aeba39f31663e9574c2 100644 (file)
@@ -20,7 +20,7 @@ extern crate hamcrest;
 use serialize::{Decoder,Encoder,Decodable,Encodable,json};
 use std::io;
 use hammer::{FlagDecoder,FlagConfig,HammerError};
-pub use util::{CliError, CliResult};
+pub use util::{CliError, CliResult, human};
 
 macro_rules! some(
   ($e:expr) => (
index 1ca4e2eeed51b1c4d43b22c4338284a00db5225f..20544a0bfacd48d04939d999d021640852ebe746 100644 (file)
@@ -20,7 +20,7 @@ use core::{Source,SourceId,PackageSet,resolver};
 use core::registry::PackageRegistry;
 use ops;
 use sources::{PathSource};
-use util::{CargoResult, Wrap, config, error};
+use util::{CargoResult, Wrap, config, error, human};
 
 pub fn compile(manifest_path: &Path) -> CargoResult<()> {
     log!(4, "compile; manifest-path={}", manifest_path.display());
@@ -37,9 +37,9 @@ pub fn compile(manifest_path: &Path) -> CargoResult<()> {
     let source_ids = package.get_source_ids();
 
     let mut registry = try!(PackageRegistry::new(source_ids, override_ids));
-    let resolved = try!(resolver::resolve(package.get_dependencies(), &mut registry).wrap("unable to resolve dependencies"));
+    let resolved = try!(resolver::resolve(package.get_dependencies(), &mut registry).wrap(human("unable to resolve dependencies")));
 
-    let packages = try!(registry.get(resolved.as_slice()).wrap("unable to get packages from source"));
+    let packages = try!(registry.get(resolved.as_slice()).wrap(human("unable to get packages from source")));
 
     debug!("packages={}", packages);
 
index 258b1cd11aef69e6be8ba87050c5fcb7ed8635ff..a23e6e023f126d27a8bb66697ab4844625480db3 100644 (file)
@@ -4,7 +4,7 @@ use core::{Package,Manifest,SourceId};
 use util::{CargoResult, human};
 
 pub fn read_manifest(contents: &[u8], source_id: &SourceId) -> CargoResult<(Manifest, Vec<Path>)> {
-    util::toml::to_manifest(contents, source_id).map_err(human)
+    util::toml::to_manifest(contents, source_id).map_err(|err| human(err.to_str()))
 }
 
 pub fn read_package(path: &Path, source_id: &SourceId) -> CargoResult<(Package, Vec<Path>)> {
index eb5fc6d683d4a85b752af3b19a84328899dabe69..59b7f42f069b5115bb1be0eb6209b8182a94afd0 100644 (file)
@@ -3,7 +3,7 @@ use std::io;
 use std::path::Path;
 use core::{Package,PackageSet,Target};
 use util;
-use util::{CargoResult, CargoError, ProcessBuilder, error, human};
+use util::{CargoResult, ProcessBuilder, error, human};
 
 type Args = Vec<String>;
 
@@ -60,15 +60,9 @@ fn rustc(root: &Path, target: &Target, dest: &Path, deps: &Path, verbose: bool)
         let rustc = prepare_rustc(root, target, *crate_type, dest, deps);
 
         try!(if verbose {
-            rustc.exec().map_err(|err| {
-                log!(5, "exec failed; error={}", err.description());
-                human(err)
-            })
+            rustc.exec().map_err(|err| human(err.to_str()))
         } else {
-            rustc.exec_with_output().and(Ok(())).map_err(|err| {
-                log!(5, "exec_with_output failed; error={}", err.description());
-                human(err)
-            })
+            rustc.exec_with_output().and(Ok(())).map_err(|err| human(err.to_str()))
         });
     }
 
index d3e3ae8520b96c455c04f679734af3a1cc9580a5..6c6b457b648ede864d1b8ecd01908fdf3e806560 100644 (file)
@@ -1,5 +1,5 @@
 use url::Url;
-use util::{CargoResult, ChainError, ProcessBuilder, process};
+use util::{CargoResult, ChainError, ProcessBuilder, process, human};
 use std::fmt;
 use std::fmt::{Show,Formatter};
 use std::str;
@@ -227,11 +227,11 @@ impl GitCheckout {
         let dirname = Path::new(self.location.dirname());
 
         cargo_try!(mkdir_recursive(&dirname, UserDir).chain_error(||
-            format!("Couldn't mkdir {}", Path::new(self.location.dirname()).display())));
+            human(format!("Couldn't mkdir {}", Path::new(self.location.dirname()).display()))));
 
         if self.location.exists() {
             cargo_try!(rmdir_recursive(&self.location).chain_error(||
-                format!("Couldn't rmdir {}", Path::new(&self.location).display())));
+                human(format!("Couldn't rmdir {}", Path::new(&self.location).display()))));
         }
 
         git!(dirname, "clone --no-checkout --quiet {} {}", self.get_source().display(), self.location.display());
@@ -262,12 +262,12 @@ fn git(path: &Path, str: &str) -> ProcessBuilder {
 }
 
 fn git_inherit(path: &Path, str: String) -> CargoResult<()> {
-    git(path, str.as_slice()).exec().chain_error(|| format!("Executing `git {}` failed", str))
+    git(path, str.as_slice()).exec().chain_error(|| human(format!("Executing `git {}` failed", str)))
 }
 
 fn git_output(path: &Path, str: String) -> CargoResult<String> {
     let output = cargo_try!(git(path, str.as_slice()).exec_with_output().chain_error(||
-        format!("Executing `git {}` failed", str)));
+        human(format!("Executing `git {}` failed", str))));
 
     Ok(to_str(output.output.as_slice()).as_slice().trim_right().to_str())
 }
index aee0bb83cae4874bf8bd821ae52227b80ad663e4..75609be159167997034fc41399cb19d108b43c8d 100644 (file)
@@ -2,7 +2,7 @@ use std::{io,fmt,os};
 use std::collections::HashMap;
 use serialize::{Encodable,Encoder};
 use toml;
-use util::{CargoResult, ChainError, Require, error, internal_error};
+use util::{CargoResult, ChainError, Require, error, internal_error, human};
 
 pub struct Config {
     home_path: Path
@@ -12,7 +12,7 @@ impl Config {
     pub fn new() -> CargoResult<Config> {
         Ok(Config {
             home_path: cargo_try!(os::homedir()
-                            .require(|| "Couldn't find the home directory"))
+                            .require(|| human("Couldn't find the home directory")))
         })
     }
 
index c23fddb726cac5501da0d2d8d0dd7fb45af6f36e..adad8a8db13b87a97867fde33929298c4bfe4bc6 100644 (file)
@@ -104,16 +104,6 @@ impl<T, E: CargoError> ChainError<T> for Result<T, E> {
     }
 }
 
-impl CargoError for &'static str {
-    fn description(&self) -> String { self.to_str() }
-    fn is_human(&self) -> bool { true }
-}
-
-impl CargoError for String {
-    fn description(&self) -> String { self.to_str() }
-    fn is_human(&self) -> bool { true }
-}
-
 impl CargoError for IoError {
     fn description(&self) -> String { self.to_str() }
 }
@@ -143,7 +133,7 @@ impl Show for ProcessError {
             Some(ExitStatus(i)) | Some(ExitSignal(i)) => i.to_str(),
             None => "never executed".to_str()
         };
-        write!(f, "process failed: `{}` (status={})", self.command, exit)
+        write!(f, "{} (status={})", self.msg, exit)
     }
 }
 
@@ -205,7 +195,12 @@ pub struct CliError {
 }
 
 impl CliError {
-    pub fn new<E: CargoError + 'static>(error: E, code: uint) -> CliError {
+    pub fn new<S: Str>(error: S, code: uint) -> CliError {
+        let error = human(error.as_slice().to_str());
+        CliError::from_boxed(error, code)
+    }
+
+    pub fn from_error<E: CargoError + 'static>(error: E, code: uint) -> CliError {
         let error = box error as Box<CargoError>;
         CliError::from_boxed(error, code)
     }
@@ -214,7 +209,7 @@ impl CliError {
         let error = if error.is_human() {
             error
         } else {
-            chain(error, "An unknown error occurred")
+            chain(error, human("An unknown error occurred"))
         };
 
         CliError { error: error, exit_code: code }
@@ -250,10 +245,13 @@ pub fn error<S1: Str>(error: S1) -> Box<CargoError> {
     } as Box<CargoError>
 }
 
-pub fn human<E: CargoError>(error: E) -> Box<CargoError> {
-    let mut concrete = error.concrete();
-    concrete.is_human = true;
-    box concrete as Box<CargoError>
+pub fn human<S: Str>(error: S) -> Box<CargoError> {
+    box ConcreteCargoError {
+        description: error.as_slice().to_str(),
+        detail: None,
+        cause: None,
+        is_human: true
+    } as Box<CargoError>
 }
 
 pub fn chain<E: CargoError>(original: Box<CargoError>, update: E) -> Box<CargoError> {
index 22898713f56ab08ac79cf8791b7529687ad84c79..413ba1a7cc104cf2a33e331eed9f1495ace7c65d 100644 (file)
@@ -7,7 +7,7 @@ use serialize::Decodable;
 use core::{SourceId,GitKind};
 use core::manifest::{LibKind,Lib};
 use core::{Summary,Manifest,Target,Dependency,PackageId};
-use util::{CargoResult, Require, error};
+use util::{CargoResult, Require, error, human};
 
 pub fn to_manifest(contents: &[u8], source_id: &SourceId) -> CargoResult<(Manifest, Vec<Path>)> {
     let root = try!(toml::parse_from_bytes(contents).map_err(|_| error("Cargo.toml is not valid Toml")));
@@ -33,7 +33,7 @@ fn toml_to_manifest(root: toml::Value) -> CargoResult<TomlManifest> {
 
     let deps = match deps {
         Some(deps) => {
-            let table = try!(deps.get_table().require(|| "dependencies must be a table")).clone();
+            let table = try!(deps.get_table().require(|| human("dependencies must be a table"))).clone();
 
             let mut deps: HashMap<String, TomlDependency> = HashMap::new();
 
@@ -45,13 +45,13 @@ fn toml_to_manifest(root: toml::Value) -> CargoResult<TomlManifest> {
 
                         for (k, v) in table.iter() {
                             let v = try!(v.get_str()
-                                         .require(|| "dependency values must be string"));
+                                         .require(|| human("dependency values must be string")));
 
                             details.insert(k.clone(), v.clone());
                         }
 
                         let version = try!(details.find_equiv(&"version")
-                                           .require(|| "dependencies must include a version")).clone();
+                                           .require(|| human("dependencies must include a version"))).clone();
 
                         deps.insert(k.clone(), DetailedDep(DetailedTomlDependency {
                             version: version,