aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2022-03-20 23:42:00 +0100
committerTeddy Wing2022-03-20 23:42:00 +0100
commitb94637ae80ed4b6b2a725c3ff22e821233be0f33 (patch)
tree2262080a9bae11cabefc62e61ba1ddd283cf54fb
parentd12125737b9068a653124c21cfc66b67c4b7704b (diff)
downloadyaqlite-b94637ae80ed4b6b2a725c3ff22e821233be0f33.tar.bz2
main: Print errors to standard error instead of panicking with `unwrap`
Use `anyhow` to add context to errors and a `main()` wrapper that prints error messages and their context to standard error.
-rw-r--r--Cargo.lock14
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs73
3 files changed, 77 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 30c6453..564ee75 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -14,6 +14,12 @@ dependencies = [
]
[[package]]
+name = "anyhow"
+version = "1.0.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
+
+[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -60,6 +66,12 @@ dependencies = [
]
[[package]]
+name = "exitcode"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193"
+
+[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -314,7 +326,9 @@ dependencies = [
name = "yaqlite"
version = "0.0.1"
dependencies = [
+ "anyhow",
"clap",
+ "exitcode",
"rusqlite",
"thiserror",
"yaml-rust-davvid",
diff --git a/Cargo.toml b/Cargo.toml
index 7b6e6b5..23ee553 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,6 +4,8 @@ version = "0.0.1"
edition = "2021"
[dependencies]
+anyhow = "1.0.56"
+exitcode = "1.1.2"
rusqlite = { version = "0.27.0", features = ["modern_sqlite"] }
thiserror = "1.0.30"
yaml-rust = { package = "yaml-rust-davvid", version = "0.5.1" }
diff --git a/src/main.rs b/src/main.rs
index 9a82d25..bb979b2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -41,6 +41,25 @@ enum Command {
fn main() {
+ match run() {
+ Ok(_) => (),
+ Err(e) => {
+ eprint!("error");
+
+ for cause in e.chain() {
+ eprint!(": {}", cause);
+ }
+
+ eprintln!();
+
+ std::process::exit(exitcode::SOFTWARE);
+ }
+ }
+}
+
+fn run() -> anyhow::Result<()> {
+ use anyhow::Context;
+
let args = Args::parse();
match args.command {
@@ -54,23 +73,37 @@ fn main() {
None => "-",
};
- let mut dbconn = rusqlite::Connection::open(database).unwrap();
+ let mut dbconn = rusqlite::Connection::open(&database)
+ .with_context(||
+ format!("can't connect to database '{}'", database)
+ )?;
let mut text_data;
if input_file == "-" {
use std::io::Read;
text_data = String::new();
- std::io::stdin().read_to_string(&mut text_data).unwrap();
+ std::io::stdin().read_to_string(&mut text_data)
+ .context("can't read from stdin")?;
} else {
- text_data = std::fs::read_to_string(input_file).unwrap();
+ text_data = std::fs::read_to_string(input_file)
+ .with_context(||
+ format!("can't read from file '{}'", input_file),
+ )?;
}
- let mut yaml_data = yaml::YamlLoader::load_from_str(&text_data).unwrap();
+ let mut yaml_data = yaml::YamlLoader::load_from_str(&text_data)
+ .context("can't parse YAML")?;
- yaqlite::insert(&mut dbconn, &table_name, &mut yaml_data).unwrap();
+ yaqlite::insert(&mut dbconn, &table_name, &mut yaml_data)
+ .context("failed to insert data")?;
- dbconn.close().unwrap();
+ dbconn.close()
+ .map_err(|e| {
+ let (_, err) = e;
+ err
+ })
+ .context("failed to close database")?;
},
Command::Select {
@@ -85,7 +118,10 @@ fn main() {
exclude_column = Some(Vec::new());
}
- let dbconn = rusqlite::Connection::open(database).unwrap();
+ let dbconn = rusqlite::Connection::open(&database)
+ .with_context(||
+ format!("can't connect to database '{}'", database)
+ )?;
let yaml_data = match primary_key {
Some(pk) => yaqlite::select_by_column(
@@ -94,14 +130,18 @@ fn main() {
&pk,
&record_id,
exclude_column.as_deref(),
- ).unwrap(),
+ ).with_context(||
+ format!("can't select record '{}'", record_id),
+ )?,
None => yaqlite::select(
&dbconn,
&table_name,
&record_id,
exclude_column.as_deref(),
- ).unwrap(),
+ ).with_context(||
+ format!("can't select record '{}'", record_id),
+ )?,
};
let stdout = std::io::stdout();
@@ -109,15 +149,24 @@ fn main() {
let mut buffer = yaqlite::yaml::IoAdapter::new(&mut stdout_handle);
let mut emitter = yaml_rust::YamlEmitter::new(&mut buffer);
emitter.multiline_strings(true);
- emitter.dump(&yaml_data).unwrap();
+ emitter.dump(&yaml_data)
+ .context("can't serialize YAML")?;
// YamlEmitter doesn't output a trailing newline.
{
use std::io::Write;
- writeln!(stdout_handle, "").unwrap();
+ writeln!(stdout_handle, "")
+ .context("failed to write to stdout")?;
}
- dbconn.close().unwrap();
+ dbconn.close()
+ .map_err(|e| {
+ let (_, err) = e;
+ err
+ })
+ .context("failed to close database")?;
},
};
+
+ Ok(())
}