aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorboastful-squirrel <boastful.squirrel@gmail.com>2019-04-21 14:27:34 +0000
committerboastful-squirrel <boastful.squirrel@gmail.com>2019-04-21 14:27:34 +0000
commit8af3ff10e2347da70c35eb45046f8a04843f7256 (patch)
tree88b48970bfd3223c30eb820c21bf5b7df8d3511f /src/main.rs
parentcargo fmt (diff)
downloadminiserve-8af3ff10e2347da70c35eb45046f8a04843f7256.tar.gz
miniserve-8af3ff10e2347da70c35eb45046f8a04843f7256.zip
Rework error system + avoid panics in main()
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs87
1 files changed, 67 insertions, 20 deletions
diff --git a/src/main.rs b/src/main.rs
index 42a43b5..fec3913 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,6 +19,8 @@ mod listing;
mod renderer;
mod themes;
+use crate::errors::{ContextualError, ContextualErrorKind};
+
#[derive(Clone)]
/// Configuration of the Miniserve application
pub struct MiniserveConfig {
@@ -57,10 +59,18 @@ pub struct MiniserveConfig {
}
fn main() {
+ match run() {
+ Ok(()) => (),
+ Err(e) => eprintln!("\n{}\n", Paint::red(e)),
+ }
+}
+
+fn run() -> Result<(), ContextualError> {
if cfg!(windows) && !Paint::enable_windows_ascii() {
Paint::disable();
}
+ let sys = actix::System::new("miniserve");
let miniserve_config = args::parse_args();
let _ = if miniserve_config.verbose {
@@ -73,16 +83,20 @@ fn main() {
&& miniserve_config
.path
.symlink_metadata()
- .expect("Can't get file metadata")
+ .map_err(|e| {
+ ContextualError::new(ContextualErrorKind::IOError(
+ "Failed to retrieve symlink's metadata".to_string(),
+ e,
+ ))
+ })?
.file_type()
.is_symlink()
{
- log::error!("The no-symlinks option cannot be used with a symlink path");
- return;
+ return Err(ContextualError::from(
+ "The no-symlinks option cannot be used with a symlink path".to_string(),
+ ));
}
- let sys = actix::System::new("miniserve");
-
let inside_config = miniserve_config.clone();
let interfaces = miniserve_config
@@ -102,7 +116,12 @@ fn main() {
})
.collect::<Vec<String>>();
- let canon_path = miniserve_config.path.canonicalize().unwrap();
+ let canon_path = miniserve_config.path.canonicalize().map_err(|e| {
+ ContextualError::new(ContextualErrorKind::IOError(
+ "Failed to resolve path to be served".to_string(),
+ e,
+ ))
+ })?;
let path_string = canon_path.to_string_lossy();
println!(
@@ -116,10 +135,20 @@ fn main() {
" Invoke with -h|--help to see options or invoke as `miniserve .` to hide this advice."
);
print!("Starting server in ");
- io::stdout().flush().unwrap();
+ io::stdout().flush().map_err(|e| {
+ ContextualError::new(ContextualErrorKind::IOError(
+ "Failed to write data".to_string(),
+ e,
+ ))
+ })?;
for c in "3… 2… 1… \n".chars() {
print!("{}", c);
- io::stdout().flush().unwrap();
+ io::stdout().flush().map_err(|e| {
+ ContextualError::new(ContextualErrorKind::IOError(
+ "Failed to write data".to_string(),
+ e,
+ ))
+ })?;
thread::sleep(Duration::from_millis(500));
}
}
@@ -148,12 +177,6 @@ fn main() {
));
}
}
- println!(
- "Serving path {path} at {addresses}",
- path = Color::Yellow.paint(path_string).bold(),
- addresses = addresses,
- );
- println!("\nQuit by pressing CTRL-C");
let socket_addresses = interfaces
.iter()
@@ -167,10 +190,18 @@ fn main() {
})
.collect::<Result<Vec<SocketAddr>, _>>();
- // Note that this should never fail, since CLI parsing succeeded
- // This means the format of each IP address is valid, and so is the port
- // Valid IpAddr + valid port == valid SocketAddr
- let socket_addresses = socket_addresses.expect("Failed to parse string as socket address");
+ let socket_addresses = match socket_addresses {
+ Ok(addresses) => addresses,
+ Err(e) => {
+ // Note that this should never fail, since CLI parsing succeeded
+ // This means the format of each IP address is valid, and so is the port
+ // Valid IpAddr + valid port == valid SocketAddr
+ return Err(ContextualError::new(ContextualErrorKind::ParseError(
+ "string as socket address".to_string(),
+ e.to_string(),
+ )));
+ }
+ };
server::new(move || {
App::with_state(inside_config.clone())
@@ -179,10 +210,26 @@ fn main() {
.configure(configure_app)
})
.bind(socket_addresses.as_slice())
- .expect("Couldn't bind server")
+ .map_err(|e| {
+ ContextualError::new(ContextualErrorKind::IOError(
+ "Failed to bind server".to_string(),
+ e,
+ ))
+ })?
.shutdown_timeout(0)
.start();
+
+ println!(
+ "Serving path {path} at {addresses}",
+ path = Color::Yellow.paint(path_string).bold(),
+ addresses = addresses,
+ );
+
+ println!("\nQuit by pressing CTRL-C");
+
let _ = sys.run();
+
+ Ok(())
}
/// Configures the Actix application
@@ -204,7 +251,7 @@ fn configure_app(app: App<MiniserveConfig>) -> App<MiniserveConfig> {
let u_r = upload_route.clone();
Some(
fs::StaticFiles::new(path)
- .expect("Couldn't create path")
+ .expect("Failed to setup static file handler")
.show_files_listing()
.files_listing_renderer(move |dir, req| {
listing::directory_listing(