refactor: use anyhow for error handling

This commit is contained in:
Philipp Matthias Schaefer 2021-02-25 20:36:14 +01:00
parent 6b35594f1a
commit 1b6835eddb
6 changed files with 30 additions and 35 deletions

7
Cargo.lock generated
View File

@ -9,6 +9,12 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "anyhow"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.42" version = "0.1.42"
@ -1297,6 +1303,7 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
name = "webldappasswd" name = "webldappasswd"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow",
"clap", "clap",
"handlebars", "handlebars",
"ldap3", "ldap3",

View File

@ -9,6 +9,7 @@ lto = true
codegen-units = 1 codegen-units = 1
[dependencies] [dependencies]
anyhow = "1.0"
clap = "2.33" clap = "2.33"
handlebars = "3.5" handlebars = "3.5"
serde = "1.0" serde = "1.0"

View File

@ -70,6 +70,7 @@ WebLDAPPasswd is published by Philipp Matthias Schäfer
WebLDAPPasswd directly depends on the following Rust libraries all published by WebLDAPPasswd directly depends on the following Rust libraries all published by
their copyright holders under the MIT License: their copyright holders under the MIT License:
* [*anyhow*](https://github.com/dtolnay/anyhow)
* [*clap*](https://clap.rs) * [*clap*](https://clap.rs)
* [*serde*](https://serde.rs) * [*serde*](https://serde.rs)
* [*serde_derive*](https://serde.rs) * [*serde_derive*](https://serde.rs)

View File

@ -1,12 +1,11 @@
use std::io::BufReader; use std::io::BufReader;
use std::fs::File; use std::fs::File;
use anyhow::{Context, Result};
use handlebars::Handlebars; use handlebars::Handlebars;
use serde_derive::Deserialize; use serde_derive::Deserialize;
use serde_json::json; use serde_json::json;
use crate::exit::exit_with_error;
fn default_ldap_url() -> String { fn default_ldap_url() -> String {
"ldap://localhost".to_string() "ldap://localhost".to_string()
} }
@ -33,24 +32,17 @@ pub struct Config {
pub port: u16, pub port: u16,
} }
pub fn check_config(config: Config) -> Config { pub fn load_config(file_path: &str) -> Result<Config> {
let hb = Handlebars::new(); let file = File::open(file_path).
with_context(|| format!("Failed to open configuration file '{}'", file_path))?;
if let Some(e) = hb.render_template(&config.dn, &json!({"username" : "foo"})).err() { let config: Config = serde_json::from_reader(BufReader::new(file))
exit_with_error(&format!("Failed to parse 'dn' ({}) in configuration file: {}", config.dn, e)) .with_context(|| format!("Failed to parse configuration file '{}'", file_path))?;
};
config Handlebars::new()
} .render_template(&config.dn, &json!({"username" : "foo"}))
.map(|_| ())
pub fn load_config(file_path: &str) -> Config { .with_context(|| format!("Failed to parse DN ({}) in configuration file '{}'", config.dn, file_path))?;
let file = match File::open(file_path) {
Ok(file) => file, Ok(config)
Err(_) => exit_with_error(&format!("Failed to open configuration file '{}'", file_path))
};
match serde_json::from_reader(BufReader::new(file)) {
Ok(config) => check_config(config),
Err(_) => exit_with_error(&format!("Failed to parse configuration file '{}'", file_path))
}
} }

View File

@ -1,4 +0,0 @@
pub fn exit_with_error(message: &str) -> ! {
eprintln!("{}", message);
std::process::exit(-1)
}

View File

@ -2,19 +2,18 @@
mod api; mod api;
mod config; mod config;
mod exit;
mod r#static; mod r#static;
use anyhow::{Context, Result};
use clap::{Arg, App, crate_version}; use clap::{Arg, App, crate_version};
use rocket::routes; use rocket::routes;
use rocket::config::{Config, Environment}; use rocket::config::{Config, Environment};
use crate::config::load_config; use crate::config::load_config;
use crate::exit::exit_with_error;
const DEFAULT_CONFIG_FILE_PATH: &str = "/etc/webldappasswd/config.json"; const DEFAULT_CONFIG_FILE_PATH: &str = "/etc/webldappasswd/config.json";
fn main() { fn main() -> Result<()> {
let matches = App::new("WebLDAPPasswd") let matches = App::new("WebLDAPPasswd")
.version(crate_version!()) .version(crate_version!())
.arg(Arg::with_name("config") .arg(Arg::with_name("config")
@ -29,16 +28,13 @@ fn main() {
.value_of("config") .value_of("config")
.unwrap_or(DEFAULT_CONFIG_FILE_PATH); .unwrap_or(DEFAULT_CONFIG_FILE_PATH);
let config = load_config(config_file_path); let config = load_config(config_file_path)?;
let rocket_config_builder = Config::build(Environment::Production) let rocket_config = Config::build(Environment::Production)
.address(&config.host) .address(&config.host)
.port(config.port); .port(config.port)
.finalize()
let rocket_config = match rocket_config_builder.finalize() { .with_context(|| format!("Bad host address ({}) in configuration file '{}'", config.host, config_file_path))?;
Ok(config) => config,
Err(e) => exit_with_error(&format!("Bad host address ({}) in configuration file: {}", config.host, e)),
};
rocket::custom(rocket_config) rocket::custom(rocket_config)
.mount("/", routes![r#static::index, .mount("/", routes![r#static::index,
@ -51,4 +47,6 @@ fn main() {
api::update]) api::update])
.manage(config) .manage(config)
.launch(); .launch();
Ok(())
} }