diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2019-04-02 00:01:24 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2019-04-02 00:01:24 +0200 |
| commit | 98bf3da24cf29ca93a3685e6cbad8d3e76d7cc4b (patch) | |
| tree | eff6127187b9da2bc84561f6800af592b7271432 | |
| parent | 9252bbdde62db9db5d564b785fbaac14220d085a (diff) | |
| parent | 4c50458d11214ff664b169017d6004e3107cb889 (diff) | |
| download | mullvadvpn-98bf3da24cf29ca93a3685e6cbad8d3e76d7cc4b.tar.xz mullvadvpn-98bf3da24cf29ca93a3685e6cbad8d3e76d7cc4b.zip | |
Merge branch 'eliminate-even-more-error-chain'
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 4 | ||||
| -rw-r--r-- | mullvad-daemon/src/logging.rs | 4 | ||||
| -rw-r--r-- | talpid-core/src/lib.rs | 14 | ||||
| -rw-r--r-- | talpid-core/src/logging.rs | 18 | ||||
| -rw-r--r-- | talpid-core/src/offline/mod.rs | 4 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/blocked_state.rs | 25 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connected_state.rs | 61 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connecting_state.rs | 67 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/disconnected_state.rs | 22 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/disconnecting_state.rs | 26 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/mod.rs | 88 |
11 files changed, 183 insertions, 150 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 55bfce8f62..37b69e2a13 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -71,9 +71,11 @@ error_chain! { } } links { - TunnelError(tunnel_state_machine::Error, tunnel_state_machine::ErrorKind); AccountHistory(account_history::Error, account_history::ErrorKind); } + foreign_links { + TunnelError(tunnel_state_machine::Error); + } } type SyncUnboundedSender<T> = ::futures::sink::Wait<UnboundedSender<T>>; diff --git a/mullvad-daemon/src/logging.rs b/mullvad-daemon/src/logging.rs index 39f5a2cd59..a12c83be30 100644 --- a/mullvad-daemon/src/logging.rs +++ b/mullvad-daemon/src/logging.rs @@ -14,10 +14,8 @@ error_chain! { display("Unable to open log file for writing: {}", path.display()) } } - links { - RotateLog(::talpid_core::logging::Error, ::talpid_core::logging::ErrorKind); - } foreign_links { + RotateLog(::talpid_core::logging::RotateLogError); SetLoggerError(log::SetLoggerError); Io(io::Error); } diff --git a/talpid-core/src/lib.rs b/talpid-core/src/lib.rs index 1147e40fd6..8de9002c1a 100644 --- a/talpid-core/src/lib.rs +++ b/talpid-core/src/lib.rs @@ -62,7 +62,11 @@ mod linux; trait ErrorExt { + /// Creates a string representation of the entire error chain. fn display_chain(&self) -> String; + + /// Like [`display_chain`] but with an extra message at the start of the chain + fn display_chain_with_msg(&self, msg: &str) -> String; } impl<E: std::error::Error> ErrorExt for E { @@ -75,4 +79,14 @@ impl<E: std::error::Error> ErrorExt for E { } s } + + fn display_chain_with_msg(&self, msg: &str) -> String { + let mut s = format!("Error: {}\nCaused by: {}", msg, self); + let mut source = self.source(); + while let Some(error) = source { + s.push_str(&format!("\nCaused by: {}", error)); + source = error.source(); + } + s + } } diff --git a/talpid-core/src/logging.rs b/talpid-core/src/logging.rs index 9f63c70a33..b41e1a3ffc 100644 --- a/talpid-core/src/logging.rs +++ b/talpid-core/src/logging.rs @@ -1,19 +1,25 @@ use std::{fs, io, path::Path}; -error_chain! {} +/// Unable to create new log file +#[derive(err_derive::Error, Debug)] +#[error(display = "Unable to create new log file")] +pub struct RotateLogError(#[error(cause)] io::Error); /// Create a new log file while backing up a previous version of it. /// /// A new log file is created with the given file name, but if a file with that name already exists /// it is backed up with the extension changed to `.old.log`. -pub fn rotate_log(file: &Path) -> Result<()> { +pub fn rotate_log(file: &Path) -> Result<(), RotateLogError> { let backup = file.with_extension("old.log"); - if let Err(error) = fs::rename(file, backup) { + if let Err(error) = fs::rename(file, &backup) { if error.kind() != io::ErrorKind::NotFound { - log::warn!("Failed to rotate log file ({})", error); + log::warn!( + "Failed to rotate log file to {}: {}", + backup.display(), + error + ); } } - fs::File::create(file).chain_err(|| "Unable to create new log file")?; - Ok(()) + fs::File::create(file).map(|_| ()).map_err(RotateLogError) } diff --git a/talpid-core/src/offline/mod.rs b/talpid-core/src/offline/mod.rs index 00b2544636..8b0077342a 100644 --- a/talpid-core/src/offline/mod.rs +++ b/talpid-core/src/offline/mod.rs @@ -17,10 +17,10 @@ mod imp; #[path = "dummy.rs"] mod imp; -pub use self::imp::is_offline; +pub use self::imp::{is_offline, Error}; pub struct MonitorHandle(imp::MonitorHandle); -pub fn spawn_monitor(sender: UnboundedSender<TunnelCommand>) -> Result<MonitorHandle, imp::Error> { +pub fn spawn_monitor(sender: UnboundedSender<TunnelCommand>) -> Result<MonitorHandle, Error> { Ok(MonitorHandle(imp::spawn_monitor(sender)?)) } diff --git a/talpid-core/src/tunnel_state_machine/blocked_state.rs b/talpid-core/src/tunnel_state_machine/blocked_state.rs index 4fd992dd4d..a080e3ab67 100644 --- a/talpid-core/src/tunnel_state_machine/blocked_state.rs +++ b/talpid-core/src/tunnel_state_machine/blocked_state.rs @@ -1,12 +1,10 @@ -use error_chain::ChainedError; -use futures::{sync::mpsc, Stream}; -use talpid_types::tunnel::BlockReason; - use super::{ - ConnectingState, DisconnectedState, EventConsequence, ResultExt, SharedTunnelStateValues, - TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper, + ConnectingState, DisconnectedState, EventConsequence, SharedTunnelStateValues, TunnelCommand, + TunnelState, TunnelStateTransition, TunnelStateWrapper, }; -use crate::firewall::FirewallPolicy; +use crate::{firewall::FirewallPolicy, ErrorExt}; +use futures::{sync::mpsc, Stream}; +use talpid_types::tunnel::BlockReason; /// No tunnel is running and all network connections are blocked. pub struct BlockedState { @@ -19,14 +17,15 @@ impl BlockedState { allow_lan: shared_values.allow_lan, }; - match shared_values - .firewall - .apply_policy(policy) - .chain_err(|| "Failed to apply firewall policy for blocked state") - { + match shared_values.firewall.apply_policy(policy) { Ok(()) => None, Err(error) => { - log::error!("{}", error.display_chain()); + log::error!( + "{}", + error.display_chain_with_msg( + "Failed to apply firewall policy for blocked state" + ) + ); Some(BlockReason::SetFirewallPolicyError) } } diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs index ffca534565..fc0c070c59 100644 --- a/talpid-core/src/tunnel_state_machine/connected_state.rs +++ b/talpid-core/src/tunnel_state_machine/connected_state.rs @@ -1,4 +1,12 @@ -use error_chain::ChainedError; +use super::{ + AfterDisconnect, BlockedState, ConnectingState, DisconnectingState, EventConsequence, + SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper, +}; +use crate::{ + firewall::FirewallPolicy, + tunnel::{CloseHandle, TunnelEvent, TunnelMetadata}, + ErrorExt, +}; use futures::{ sync::{mpsc, oneshot}, Async, Future, Stream, @@ -8,16 +16,6 @@ use talpid_types::{ tunnel::BlockReason, }; -use super::{ - AfterDisconnect, BlockedState, ConnectingState, DisconnectingState, EventConsequence, Result, - ResultExt, SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition, - TunnelStateWrapper, -}; -use crate::{ - firewall::FirewallPolicy, - tunnel::{CloseHandle, TunnelEvent, TunnelMetadata}, -}; - pub struct ConnectedStateBootstrap { pub metadata: TunnelMetadata, pub tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>, @@ -46,7 +44,10 @@ impl ConnectedState { } } - fn set_firewall_policy(&self, shared_values: &mut SharedTunnelStateValues) -> Result<()> { + fn set_firewall_policy( + &self, + shared_values: &mut SharedTunnelStateValues, + ) -> Result<(), crate::firewall::Error> { // If a proxy is specified we need to pass it on as the peer endpoint. let peer_endpoint = self.get_endpoint_from_params(); @@ -55,10 +56,7 @@ impl ConnectedState { tunnel: self.metadata.clone(), allow_lan: shared_values.allow_lan, }; - shared_values - .firewall - .apply_policy(policy) - .chain_err(|| "Failed to apply firewall policy for connected state") + shared_values.firewall.apply_policy(policy) } fn get_endpoint_from_params(&self) -> Endpoint { @@ -71,7 +69,10 @@ impl ConnectedState { } } - fn set_dns(&self, shared_values: &mut SharedTunnelStateValues) -> Result<()> { + fn set_dns( + &self, + shared_values: &mut SharedTunnelStateValues, + ) -> Result<(), crate::dns::Error> { let mut dns_ips = vec![self.metadata.ipv4_gateway.into()]; if let Some(ipv6_gateway) = self.metadata.ipv6_gateway { dns_ips.push(ipv6_gateway.into()); @@ -80,16 +81,11 @@ impl ConnectedState { shared_values .dns_monitor .set(&self.metadata.interface, &dns_ips) - .chain_err(|| "Failed to set system DNS settings") } fn reset_dns(shared_values: &mut SharedTunnelStateValues) { - if let Err(error) = shared_values - .dns_monitor - .reset() - .chain_err(|| "Unable to reset DNS") - { - log::error!("{}", error.display_chain()); + if let Err(error) = shared_values.dns_monitor.reset() { + log::error!("{}", error.display_chain_with_msg("Unable to reset DNS")); } } @@ -119,7 +115,12 @@ impl ConnectedState { match self.set_firewall_policy(shared_values) { Ok(()) => SameState(self), Err(error) => { - log::error!("{}", error.display_chain()); + log::error!( + "{}", + error.display_chain_with_msg( + "Failed to apply firewall policy for connected state" + ) + ); self.disconnect( shared_values, AfterDisconnect::Block(BlockReason::SetFirewallPolicyError), @@ -201,7 +202,10 @@ impl TunnelState for ConnectedState { let tunnel_endpoint = connected_state.tunnel_parameters.get_tunnel_endpoint(); if let Err(error) = connected_state.set_firewall_policy(shared_values) { - log::error!("{}", error.display_chain()); + log::error!( + "{}", + error.display_chain_with_msg("Failed to apply firewall policy for connected state") + ); DisconnectingState::enter( shared_values, ( @@ -211,7 +215,10 @@ impl TunnelState for ConnectedState { ), ) } else if let Err(error) = connected_state.set_dns(shared_values) { - log::error!("{}", error.display_chain()); + log::error!( + "{}", + error.display_chain_with_msg("Failed to set system DNS settings") + ); DisconnectingState::enter( shared_values, ( diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index 77c8e41f75..faa8f77c78 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -1,3 +1,18 @@ +use super::{ + AfterDisconnect, BlockedState, ConnectedState, ConnectedStateBootstrap, DisconnectingState, + EventConsequence, SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition, + TunnelStateWrapper, +}; +use crate::{ + firewall::FirewallPolicy, + tunnel::{self, CloseHandle, TunnelEvent, TunnelMetadata, TunnelMonitor}, + ErrorExt, +}; +use futures::{ + sync::{mpsc, oneshot}, + Async, Future, Stream, +}; +use log::{debug, error, info, trace, warn}; use std::{ ffi::OsString, net::IpAddr, @@ -5,28 +20,11 @@ use std::{ thread, time::{Duration, Instant}, }; - -use error_chain::ChainedError; -use futures::{ - sync::{mpsc, oneshot}, - Async, Future, Stream, -}; -use log::{debug, error, info, trace, warn}; use talpid_types::{ net::{openvpn, TunnelParameters}, tunnel::BlockReason, }; -use super::{ - AfterDisconnect, BlockedState, ConnectedState, ConnectedStateBootstrap, DisconnectingState, - EventConsequence, SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition, - TunnelStateWrapper, -}; -use crate::{ - firewall::FirewallPolicy, - tunnel::{self, CloseHandle, TunnelEvent, TunnelMetadata, TunnelMonitor}, -}; - const MIN_TUNNEL_ALIVE_TIME: Duration = Duration::from_millis(1000); @@ -35,8 +33,6 @@ const TUNNEL_INTERFACE_ALIAS: Option<&str> = Some("Mullvad"); #[cfg(not(windows))] const TUNNEL_INTERFACE_ALIAS: Option<&str> = None; -error_chain! {} - /// The tunnel has been started, but it is not established/functional. pub struct ConnectingState { tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>, @@ -50,7 +46,7 @@ impl ConnectingState { fn set_firewall_policy( shared_values: &mut SharedTunnelStateValues, params: &TunnelParameters, - ) -> Result<()> { + ) -> Result<(), crate::firewall::Error> { let proxy = &get_openvpn_proxy_settings(¶ms); let endpoint = params.get_tunnel_endpoint().endpoint; @@ -64,10 +60,7 @@ impl ConnectingState { pingable_hosts: gateway_list_from_params(params), allow_lan: shared_values.allow_lan, }; - shared_values - .firewall - .apply_policy(policy) - .chain_err(|| "Failed to apply firewall policy for connecting state") + shared_values.firewall.apply_policy(policy) } fn start_tunnel( @@ -145,13 +138,17 @@ impl ConnectingState { ), _, ) => { - let chained_error = error.chain_err(|| "TAP adapter problem detected"); - warn!("{}", chained_error.display_chain()); + warn!( + "{}", + error.display_chain_with_msg("TAP adapter problem detected") + ); Some(BlockReason::TapAdapterProblem) } error => { - let chained_error = error.chain_err(|| "Tunnel has stopped unexpectedly"); - warn!("{}", chained_error.display_chain()); + warn!( + "{}", + error.display_chain_with_msg("Tunnel has stopped unexpectedly") + ); None } }, @@ -181,7 +178,12 @@ impl ConnectingState { match Self::set_firewall_policy(shared_values, &self.tunnel_parameters) { Ok(()) => SameState(self), Err(error) => { - error!("{}", error.display_chain()); + error!( + "{}", + error.display_chain_with_msg( + "Failed to apply firewall policy for connecting state" + ) + ); NewState(DisconnectingState::enter( shared_values, @@ -326,7 +328,12 @@ impl TunnelState for ConnectingState { None => BlockedState::enter(shared_values, BlockReason::NoMatchingRelay), Some(tunnel_parameters) => { if let Err(error) = Self::set_firewall_policy(shared_values, &tunnel_parameters) { - error!("{}", error.display_chain()); + error!( + "{}", + error.display_chain_with_msg( + "Failed to apply firewall policy for connecting state" + ) + ); BlockedState::enter(shared_values, BlockReason::StartTunnelError) } else { match Self::start_tunnel( diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs index 299d00d303..437ef865e7 100644 --- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs +++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs @@ -1,9 +1,8 @@ use super::{ - BlockedState, ConnectingState, EventConsequence, ResultExt, SharedTunnelStateValues, - TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper, + BlockedState, ConnectingState, EventConsequence, SharedTunnelStateValues, TunnelCommand, + TunnelState, TunnelStateTransition, TunnelStateWrapper, }; -use crate::firewall::FirewallPolicy; -use error_chain::ChainedError; +use crate::{firewall::FirewallPolicy, ErrorExt}; use futures::{sync::mpsc, Stream}; /// No tunnel is running. @@ -15,18 +14,19 @@ impl DisconnectedState { let policy = FirewallPolicy::Blocked { allow_lan: shared_values.allow_lan, }; - shared_values - .firewall - .apply_policy(policy) - .chain_err(|| "Failed to apply blocking firewall policy for disconnected state") + shared_values.firewall.apply_policy(policy).map_err(|e| { + e.display_chain_with_msg( + "Failed to apply blocking firewall policy for disconnected state", + ) + }) } else { shared_values .firewall .reset_policy() - .chain_err(|| "Failed to reset firewall policy") + .map_err(|e| e.display_chain_with_msg("Failed to reset firewall policy")) }; - if let Err(error) = result { - log::error!("{}", error.display_chain()); + if let Err(error_chain) = result { + log::error!("{}", error_chain); } } } diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs index 6f470fe370..42b2b230ba 100644 --- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs @@ -1,18 +1,15 @@ -use std::thread; - -use error_chain::ChainedError; +use super::{ + BlockedState, ConnectingState, DisconnectedState, EventConsequence, SharedTunnelStateValues, + TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper, +}; +use crate::{tunnel::CloseHandle, ErrorExt}; use futures::{ sync::{mpsc, oneshot}, Async, Future, Stream, }; +use std::thread; use talpid_types::tunnel::{ActionAfterDisconnect, BlockReason}; -use super::{ - BlockedState, ConnectingState, DisconnectedState, EventConsequence, ResultExt, - SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper, -}; -use crate::tunnel::CloseHandle; - /// This state is active from when we manually trigger a tunnel kill until the tunnel wait /// operation (TunnelExit) returned. pub struct DisconnectingState { @@ -141,12 +138,11 @@ impl TunnelState for DisconnectingState { (close_handle, exited, after_disconnect): Self::Bootstrap, ) -> (TunnelStateWrapper, TunnelStateTransition) { thread::spawn(move || { - let close_result = close_handle - .close() - .chain_err(|| "Failed to close the tunnel"); - - if let Err(error) = close_result { - log::error!("{}", error.display_chain()); + if let Err(error) = close_handle.close() { + log::error!( + "{}", + error.display_chain_with_msg("Failed to close the tunnel") + ); } }); diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index 4e85e9a0be..74874ab39a 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -7,46 +7,49 @@ mod connecting_state; mod disconnected_state; mod disconnecting_state; +use self::{ + blocked_state::BlockedState, + connected_state::{ConnectedState, ConnectedStateBootstrap}, + connecting_state::ConnectingState, + disconnected_state::DisconnectedState, + disconnecting_state::{AfterDisconnect, DisconnectingState}, +}; +use crate::{dns::DnsMonitor, firewall::Firewall, mpsc::IntoSender, offline, ErrorExt}; +use futures::{sync::mpsc, Async, Future, Poll, Stream}; use std::{ + io, path::{Path, PathBuf}, sync::mpsc as sync_mpsc, thread, }; - -use error_chain::ChainedError; -use futures::{sync::mpsc, Async, Future, Poll, Stream}; -use tokio_core::reactor::Core; - use talpid_types::{ net::TunnelParameters, tunnel::{BlockReason, TunnelStateTransition}, }; +use tokio_core::reactor::Core; -use self::{ - blocked_state::BlockedState, - connected_state::{ConnectedState, ConnectedStateBootstrap}, - connecting_state::ConnectingState, - disconnected_state::DisconnectedState, - disconnecting_state::{AfterDisconnect, DisconnectingState}, -}; -use crate::{dns::DnsMonitor, firewall::Firewall, mpsc::IntoSender, offline}; +/// Errors that can happen when setting up or using the state machine. +#[derive(err_derive::Error, Debug)] +pub enum Error { + /// Unable to spawn offline state monitor + #[error(display = "Unable to spawn offline state monitor")] + OfflineMonitorError(#[error(cause)] crate::offline::Error), -error_chain! { - errors { - /// An error occurred while setting up the network security. - FirewallError { - description("Firewall error") - } - /// Unable to start the DNS settings monitor and enforcer. - DnsMonitorError { - description("Unable to start the DNS settings enforcer and monitor") - } - /// An error occurred while attempting to set up the event loop for the tunnel state - /// machine. - ReactorError { - description("Failed to initialize tunnel state machine event loop executor") - } - } + /// Failed to initialize the system firewall integration. + #[error(display = "Failed to initialize the system firewall integration")] + InitFirewallError(#[error(cause)] crate::firewall::Error), + + /// Failed to initialize the system DNS manager and monitor. + #[error(display = "Failed to initialize the system DNS manager and monitor")] + InitDnsMonitorError(#[error(cause)] crate::dns::Error), + + /// Failed to initialize tunnel state machine event loop executor + #[error(display = "Failed to initialize tunnel state machine event loop executor")] + ReactorError(#[error(cause)] io::Error), + + /// Failed to send state change event to listener + #[error(display = "Failed to send state change event to listener")] + SendStateChange, } /// Spawn the tunnel state machine thread, returning a channel for sending tunnel commands. @@ -58,14 +61,14 @@ pub fn spawn<P, T>( resource_dir: PathBuf, cache_dir: P, state_change_listener: IntoSender<TunnelStateTransition, T>, -) -> Result<mpsc::UnboundedSender<TunnelCommand>> +) -> Result<mpsc::UnboundedSender<TunnelCommand>, Error> where P: AsRef<Path> + Send + 'static, T: From<TunnelStateTransition> + Send + 'static, { let (command_tx, command_rx) = mpsc::unbounded(); - let offline_monitor = offline::spawn_monitor(command_tx.clone()) - .chain_err(|| "Unable to spawn offline state monitor")?; + let offline_monitor = + offline::spawn_monitor(command_tx.clone()).map_err(Error::OfflineMonitorError)?; let is_offline = offline::is_offline(); let (startup_result_tx, startup_result_rx) = sync_mpsc::channel(); @@ -86,10 +89,11 @@ where "Tunnel state machine won't be started because the owner thread crashed", ); - if let Err(error) = reactor.run(event_loop) { - let chained_error = - Error::with_chain(error, "Tunnel state machine exited with an error"); - log::error!("{}", chained_error.display_chain()); + if let Err(e) = reactor.run(event_loop) { + log::error!( + "{}", + e.display_chain_with_msg("Tunnel state machine exited with an error") + ); } } Err(startup_error) => { @@ -117,11 +121,11 @@ fn create_event_loop<T>( cache_dir: impl AsRef<Path>, commands: mpsc::UnboundedReceiver<TunnelCommand>, state_change_listener: IntoSender<TunnelStateTransition, T>, -) -> Result<(Core, impl Future<Item = (), Error = Error>)> +) -> Result<(Core, impl Future<Item = (), Error = Error>), Error> where T: From<TunnelStateTransition> + Send + 'static, { - let reactor = Core::new().chain_err(|| ErrorKind::ReactorError)?; + let reactor = Core::new().map_err(Error::ReactorError)?; let state_machine = TunnelStateMachine::new( allow_lan, block_when_disconnected, @@ -136,7 +140,7 @@ where let future = state_machine.for_each(move |state_change_event| { state_change_listener .send(state_change_event) - .chain_err(|| "Failed to send state change event to listener") + .map_err(|_| Error::SendStateChange) }); Ok((reactor, future)) @@ -180,9 +184,9 @@ impl TunnelStateMachine { resource_dir: PathBuf, cache_dir: impl AsRef<Path>, commands: mpsc::UnboundedReceiver<TunnelCommand>, - ) -> Result<Self> { - let firewall = Firewall::new().chain_err(|| ErrorKind::FirewallError)?; - let dns_monitor = DnsMonitor::new(cache_dir).chain_err(|| ErrorKind::DnsMonitorError)?; + ) -> Result<Self, Error> { + let firewall = Firewall::new().map_err(Error::InitFirewallError)?; + let dns_monitor = DnsMonitor::new(cache_dir).map_err(Error::InitDnsMonitorError)?; let mut shared_values = SharedTunnelStateValues { firewall, dns_monitor, |
