diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2017-02-09 11:18:52 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2017-02-09 11:18:52 +0100 |
| commit | 82890bc9840f77973fa7c48d72d9e51004c75f40 (patch) | |
| tree | dc75d9ad991d368ebe6dbd6bac591e813fe228dd /talpid_cli/src | |
| parent | b460c4c138ad283746e12604975d9d1235381ed4 (diff) | |
| parent | 9d551d691a5b9981fb2c1d80801031889ca022a0 (diff) | |
| download | mullvadvpn-82890bc9840f77973fa7c48d72d9e51004c75f40.tar.xz mullvadvpn-82890bc9840f77973fa7c48d72d9e51004c75f40.zip | |
Merge branch 'error-chain'
Diffstat (limited to 'talpid_cli/src')
| -rw-r--r-- | talpid_cli/src/main.rs | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/talpid_cli/src/main.rs b/talpid_cli/src/main.rs index a174d7ed37..4a4239f622 100644 --- a/talpid_cli/src/main.rs +++ b/talpid_cli/src/main.rs @@ -1,34 +1,49 @@ +// `error_chain!` can recurse deeply +#![recursion_limit = "1024"] + extern crate talpid_core; #[macro_use] extern crate clap; +#[macro_use] +extern crate error_chain; use std::io::{self, Read, Write}; use std::sync::mpsc::{self, Receiver}; use std::thread; use talpid_core::process::OpenVpnCommand; -use talpid_core::process::monitor::{ChildMonitor, TransitionResult, ChildSpawner}; +use talpid_core::process::monitor::{ChildMonitor, ChildSpawner}; mod cli; use cli::Args; -/// Macro for printing to stderr. Will simply do nothing if the printing fails for some reason. -macro_rules! eprintln { - ($($arg:tt)*) => ( - use std::io::Write; - let _ = writeln!(&mut ::std::io::stderr(), $($arg)* ); - ) + +error_chain! { + links { + Monitor(talpid_core::process::monitor::Error, talpid_core::process::monitor::ErrorKind); + } } + fn main() { - let args = cli::parse_args_or_exit(); + if let Err(ref e) = run() { + println!("error: {}", e); + for e in e.iter().skip(1) { + println!("caused by: {}", e); + } + if let Some(backtrace) = e.backtrace() { + println!("backtrace: {:?}", backtrace); + } + ::std::process::exit(1); + } +} +fn run() -> Result<()> { + let args = cli::parse_args_or_exit(); let command = create_openvpn_command(&args); let monitor = ChildMonitor::new(command); - if let Err(e) = main_loop(monitor) { - eprintln!("OpenVPN failed: {}", e); - } + main_loop(monitor) } fn create_openvpn_command(args: &Args) -> OpenVpnCommand { @@ -41,27 +56,28 @@ fn create_openvpn_command(args: &Args) -> OpenVpnCommand { command } -fn main_loop<S>(mut monitor: ChildMonitor<S>) -> TransitionResult<()> +fn main_loop<S>(mut monitor: ChildMonitor<S>) -> Result<()> where S: ChildSpawner { loop { - let rx = start_monitor(&mut monitor)?; + let rx = start_monitor(&mut monitor).chain_err(|| "Unable to start OpenVPN")?; let clean_exit = rx.recv().unwrap(); println!("Monitored process exited. clean: {}", clean_exit); std::thread::sleep(std::time::Duration::from_millis(500)); } } -fn start_monitor<S>(monitor: &mut ChildMonitor<S>) -> TransitionResult<Receiver<bool>> +fn start_monitor<S>(monitor: &mut ChildMonitor<S>) -> Result<Receiver<bool>> where S: ChildSpawner { let (tx, rx) = mpsc::channel(); let callback = move |clean| tx.send(clean).unwrap(); - monitor.start(callback).map(|(stdout, stderr)| { - stdout.map(|stream| pass_io(stream, io::stdout())); - stderr.map(|stream| pass_io(stream, io::stderr())); - rx - }) + Ok(monitor.start(callback) + .map(|(stdout, stderr)| { + stdout.map(|stream| pass_io(stream, io::stdout())); + stderr.map(|stream| pass_io(stream, io::stderr())); + rx + })?) } fn pass_io<I, O>(mut input: I, mut output: O) |
