diff --git a/src/config.rs b/src/config.rs
index 859eb03..161b4e7 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -57,6 +57,10 @@ impl Config {
             output.trim_end().to_owned()
         };
 
-        Ok(output)
+        if output.is_empty() {
+            Err(Error::Cancelled)
+        } else {
+            Ok(output)
+        }
     }
 }
diff --git a/src/error.rs b/src/error.rs
index 9eea3c6..2b86b76 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -22,6 +22,8 @@ pub enum Error {
     MimeDetect(#[from] mime_detective::DetectiveError),
     #[error("error spawning selector process '{0}'")]
     Selector(String),
+    #[error("selection cancelled")]
+    Cancelled,
 }
 
 pub type Result<T, E = Error> = std::result::Result<T, E>;
diff --git a/src/main.rs b/src/main.rs
index 9a182ee..7285dd0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -54,14 +54,19 @@ fn main() -> Result<()> {
     }();
 
     match (res, atty::is(atty::Stream::Stdout)) {
-        (Err(e), true) => eprintln!("{}", e),
+        (Err(e), _) if matches!(e, Error::Cancelled) => {
+            std::process::exit(1);
+        }
+        (Err(e), true) => {
+            eprintln!("{}", e);
+            std::process::exit(1);
+        }
         (Err(e), false) => {
             std::process::Command::new("notify-send")
                 .args(&["handlr error", &e.to_string()])
                 .spawn()?;
+            std::process::exit(1);
         }
-        _ => {}
-    };
-
-    Ok(())
+        _ => Ok(()),
+    }
 }