diff --git a/city-pop/src/main.rs b/city-pop/src/main.rs
index 63d0715a6761f8d43c9713c216d6e646cfb7f898..59743668830a61241ff1ca1e3fe284060ae826e3 100644
--- a/city-pop/src/main.rs
+++ b/city-pop/src/main.rs
@@ -4,10 +4,50 @@ extern crate csv;
 
 
 use getopts::Options;
-use std::{env,fs,io};
+use std::{env,fmt,fs,io,process};
 use std::error::Error;
 use std::path::Path;
 
+
+#[derive(Debug)]
+enum CliError {
+    Io(io::Error),
+    Csv(csv::Error),
+    NotFound,
+}
+
+impl fmt::Display for CliError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            CliError::Io(ref err) => err.fmt(f),
+            CliError::Csv(ref err) => err.fmt(f),
+            CliError::NotFound => write!(f,"No matching cities with a population were found."),
+        }
+    }
+}
+
+impl Error for CliError {
+    fn description(&self) -> &str {
+        match *self {
+            CliError::Io(ref err) => err.description(),
+            CliError::Csv(ref err) => err.description(),
+            CliError::NotFound => "not found",
+        }
+    }
+}
+
+impl From<io::Error> for CliError {
+    fn from(err: io::Error) -> CliError {
+        CliError::Io(err)
+    }
+}
+
+impl From<csv::Error> for CliError {
+    fn from(err: csv::Error) -> CliError {
+        CliError::Csv(err)
+    }
+}
+
 // This struct represents the data in each row of the CSV file.
 // Type based decoding absolves us of a lot of the nitty gritty error
 // handling, like parsing strings as integers or floats.
@@ -47,7 +87,7 @@ fn print_usage(program: &str, opts: Options) {
 }
 
 fn search<P: AsRef<Path>> (file_path: &Option<P>, city: &str)
-                                 -> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
+                                 -> Result<Vec<PopulationCount>, CliError> {
     let mut found = vec![];
     let input: Box<io::Read> = match *file_path {
         None => Box::new(io::stdin()),
@@ -68,7 +108,7 @@ fn search<P: AsRef<Path>> (file_path: &Option<P>, city: &str)
         }
     }
     if found.is_empty() {
-        Err(From::from("No matching cities with a population were found."))
+        Err(CliError::NotFound)
     } else {
         Ok(found)
     }
@@ -81,7 +121,8 @@ fn main() {
     let mut opts = Options::new();
     opts.optopt("f","file", "Choose an input file, instead of using STDIN.","NAME");
     opts.optflag("h","help","Show this usage message.");
-
+    opts.optflag("q","quit","Silences errors and warnings.");
+    
     let matches = match opts.parse(&args[1..]) {
         Ok(m) => { m }
         Err(e) => { panic!(e.to_string()) }
@@ -101,8 +142,12 @@ fn main() {
         return;
     };
 
-    for pop in search(&data_file, &city).unwrap() {
-        println!("{}, {}: {:?}",pop.city, pop.country, pop.count);
+    match search(&data_file, &city) {
+        Err(CliError::NotFound) if matches.opt_present("q") => process::exit(1),
+        Err(err) => panic!("{}", err),
+        Ok(pops) => for pop in pops {
+            println!("{}, {}: {:?}",pop.city, pop.country, pop.count);
+        }
     }
 
 }