refactor: improve error handle (#195)
This commit is contained in:
parent
c92e45f2da
commit
29a04c8d74
5 changed files with 17 additions and 25 deletions
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use clap::builder::PossibleValuesParser;
|
use clap::builder::PossibleValuesParser;
|
||||||
use clap::{value_parser, Arg, ArgAction, ArgMatches, Command};
|
use clap::{value_parser, Arg, ArgAction, ArgMatches, Command};
|
||||||
use clap_complete::{generate, Generator, Shell};
|
use clap_complete::{generate, Generator, Shell};
|
||||||
|
@ -380,7 +380,7 @@ impl Args {
|
||||||
p.push(path); // If path is absolute, it replaces the current path.
|
p.push(path); // If path is absolute, it replaces the current path.
|
||||||
std::fs::canonicalize(p)
|
std::fs::canonicalize(p)
|
||||||
})
|
})
|
||||||
.map_err(|err| anyhow!("Failed to access path `{}`: {}", path.display(), err,))
|
.with_context(|| format!("Failed to access path `{}`", path.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_assets_path<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
|
fn parse_assets_path<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
|
||||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -18,7 +18,7 @@ use crate::server::{Request, Server};
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
use crate::tls::{TlsAcceptor, TlsStream};
|
use crate::tls::{TlsAcceptor, TlsStream};
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use std::net::{IpAddr, SocketAddr, TcpListener as StdTcpListener};
|
use std::net::{IpAddr, SocketAddr, TcpListener as StdTcpListener};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -35,14 +35,7 @@ use hyper::service::{make_service_fn, service_fn};
|
||||||
use rustls::ServerConfig;
|
use rustls::ServerConfig;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() -> Result<()> {
|
||||||
run().await.unwrap_or_else(|err| {
|
|
||||||
eprintln!("error: {err}");
|
|
||||||
std::process::exit(1);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run() -> Result<()> {
|
|
||||||
logger::init().map_err(|e| anyhow!("Failed to init logger, {e}"))?;
|
logger::init().map_err(|e| anyhow!("Failed to init logger, {e}"))?;
|
||||||
let cmd = build_cli();
|
let cmd = build_cli();
|
||||||
let matches = cmd.get_matches();
|
let matches = cmd.get_matches();
|
||||||
|
@ -94,7 +87,7 @@ fn serve(
|
||||||
match bind_addr {
|
match bind_addr {
|
||||||
BindAddr::Address(ip) => {
|
BindAddr::Address(ip) => {
|
||||||
let incoming = create_addr_incoming(SocketAddr::new(*ip, port))
|
let incoming = create_addr_incoming(SocketAddr::new(*ip, port))
|
||||||
.map_err(|e| anyhow!("Failed to bind `{ip}:{port}`, {e}"))?;
|
.with_context(|| format!("Failed to bind `{ip}:{port}`"))?;
|
||||||
match args.tls.as_ref() {
|
match args.tls.as_ref() {
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
Some((certs, key)) => {
|
Some((certs, key)) => {
|
||||||
|
@ -134,7 +127,7 @@ fn serve(
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
let listener = tokio::net::UnixListener::bind(path)
|
let listener = tokio::net::UnixListener::bind(path)
|
||||||
.map_err(|e| anyhow!("Failed to bind `{}`, {e}", path.display()))?;
|
.with_context(|| format!("Failed to bind `{}`", path.display()))?;
|
||||||
let acceptor = unix::UnixAcceptor::from_listener(listener);
|
let acceptor = unix::UnixAcceptor::from_listener(listener);
|
||||||
let new_service = make_service_fn(move |_| serve_func(None));
|
let new_service = make_service_fn(move |_| serve_func(None));
|
||||||
let server = tokio::spawn(hyper::Server::builder(acceptor).serve(new_service));
|
let server = tokio::spawn(hyper::Server::builder(acceptor).serve(new_service));
|
||||||
|
@ -181,8 +174,8 @@ fn print_listening(args: Arc<Args>) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ipv4 || ipv6 {
|
if ipv4 || ipv6 {
|
||||||
let ifaces = if_addrs::get_if_addrs()
|
let ifaces =
|
||||||
.map_err(|e| anyhow!("Failed to get local interface addresses: {e}"))?;
|
if_addrs::get_if_addrs().with_context(|| "Failed to get local interface addresses")?;
|
||||||
for iface in ifaces.into_iter() {
|
for iface in ifaces.into_iter() {
|
||||||
let local_ip = iface.ip();
|
let local_ip = iface.ip();
|
||||||
if ipv4 && local_ip.is_ipv4() {
|
if ipv4 && local_ip.is_ipv4() {
|
||||||
|
|
11
src/tls.rs
11
src/tls.rs
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Context as AnyhowContext, Result};
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
use futures::ready;
|
use futures::ready;
|
||||||
use hyper::server::accept::Accept;
|
use hyper::server::accept::Accept;
|
||||||
|
@ -128,12 +128,11 @@ impl Accept for TlsAcceptor {
|
||||||
pub fn load_certs<T: AsRef<Path>>(filename: T) -> Result<Vec<Certificate>> {
|
pub fn load_certs<T: AsRef<Path>>(filename: T) -> Result<Vec<Certificate>> {
|
||||||
// Open certificate file.
|
// Open certificate file.
|
||||||
let cert_file = fs::File::open(filename.as_ref())
|
let cert_file = fs::File::open(filename.as_ref())
|
||||||
.map_err(|e| anyhow!("Failed to access `{}`, {e}", filename.as_ref().display()))?;
|
.with_context(|| format!("Failed to access `{}`", filename.as_ref().display()))?;
|
||||||
let mut reader = io::BufReader::new(cert_file);
|
let mut reader = io::BufReader::new(cert_file);
|
||||||
|
|
||||||
// Load and return certificate.
|
// Load and return certificate.
|
||||||
let certs =
|
let certs = rustls_pemfile::certs(&mut reader).with_context(|| "Failed to load certificate")?;
|
||||||
rustls_pemfile::certs(&mut reader).map_err(|_| anyhow!("Failed to load certificate"))?;
|
|
||||||
if certs.is_empty() {
|
if certs.is_empty() {
|
||||||
bail!("No supported certificate in file");
|
bail!("No supported certificate in file");
|
||||||
}
|
}
|
||||||
|
@ -143,12 +142,12 @@ pub fn load_certs<T: AsRef<Path>>(filename: T) -> Result<Vec<Certificate>> {
|
||||||
// Load private key from file.
|
// Load private key from file.
|
||||||
pub fn load_private_key<T: AsRef<Path>>(filename: T) -> Result<PrivateKey> {
|
pub fn load_private_key<T: AsRef<Path>>(filename: T) -> Result<PrivateKey> {
|
||||||
let key_file = fs::File::open(filename.as_ref())
|
let key_file = fs::File::open(filename.as_ref())
|
||||||
.map_err(|e| anyhow!("Failed to access `{}`, {e}", filename.as_ref().display()))?;
|
.with_context(|| format!("Failed to access `{}`", filename.as_ref().display()))?;
|
||||||
let mut reader = io::BufReader::new(key_file);
|
let mut reader = io::BufReader::new(key_file);
|
||||||
|
|
||||||
// Load and return a single private key.
|
// Load and return a single private key.
|
||||||
let keys = rustls_pemfile::read_all(&mut reader)
|
let keys = rustls_pemfile::read_all(&mut reader)
|
||||||
.map_err(|e| anyhow!("There was a problem with reading private key: {e}"))?
|
.with_context(|| "There was a problem with reading private key")?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find_map(|item| match item {
|
.find_map(|item| match item {
|
||||||
rustls_pemfile::Item::RSAKey(key)
|
rustls_pemfile::Item::RSAKey(key)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
path::Path,
|
path::Path,
|
||||||
|
@ -8,7 +8,7 @@ use std::{
|
||||||
pub fn unix_now() -> Result<Duration> {
|
pub fn unix_now() -> Result<Duration> {
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.map_err(|err| anyhow!("Invalid system time, {err}"))
|
.with_context(|| "Invalid system time")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode_uri(v: &str) -> String {
|
pub fn encode_uri(v: &str) -> String {
|
||||||
|
|
|
@ -37,7 +37,7 @@ fn wrong_path_cert() -> Result<(), Error> {
|
||||||
.args(["--tls-cert", "wrong", "--tls-key", "tests/data/key.pem"])
|
.args(["--tls-cert", "wrong", "--tls-key", "tests/data/key.pem"])
|
||||||
.assert()
|
.assert()
|
||||||
.failure()
|
.failure()
|
||||||
.stderr(contains("error: Failed to access `wrong`"));
|
.stderr(contains("Failed to access `wrong`"));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ fn wrong_path_key() -> Result<(), Error> {
|
||||||
.args(["--tls-cert", "tests/data/cert.pem", "--tls-key", "wrong"])
|
.args(["--tls-cert", "tests/data/cert.pem", "--tls-key", "wrong"])
|
||||||
.assert()
|
.assert()
|
||||||
.failure()
|
.failure()
|
||||||
.stderr(contains("error: Failed to access `wrong`"));
|
.stderr(contains("Failed to access `wrong`"));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue