Die error_chain, die (#10747)

* Replace error chain for network error

* Fix usages and add manual From impls

* OnDemand Error and remove remaining dependencies

* Die error_chain, die.

* DIE

* Hasta la vista, baby
This commit is contained in:
Andrew Jones 2019-06-17 07:44:59 +01:00 committed by David
parent dbdb57a8c0
commit bf55db4c7e
29 changed files with 214 additions and 225 deletions

5
Cargo.lock generated
View File

@ -1013,6 +1013,7 @@ version = "1.12.0"
dependencies = [ dependencies = [
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0", "common-types 0.1.0",
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.12.0", "ethcore 1.12.0",
"ethcore-blockchain 0.1.0", "ethcore-blockchain 0.1.0",
@ -1106,7 +1107,7 @@ name = "ethcore-network"
version = "1.12.0" version = "1.12.0"
dependencies = [ dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-io 1.12.0", "ethcore-io 1.12.0",
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.3.0", "ethkey 0.3.0",
@ -1243,7 +1244,7 @@ name = "ethcore-service"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.12.0", "ethcore 1.12.0",
"ethcore-blockchain 0.1.0", "ethcore-blockchain 0.1.0",
"ethcore-db 0.1.0", "ethcore-db 0.1.0",

View File

@ -10,6 +10,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
log = "0.4" log = "0.4"
parity-bytes = "0.1" parity-bytes = "0.1"
common-types = { path = "../types" } common-types = { path = "../types" }
derive_more = "0.14.0"
ethcore = { path = ".."} ethcore = { path = ".."}
ethcore-db = { path = "../db" } ethcore-db = { path = "../db" }
ethcore-blockchain = { path = "../blockchain" } ethcore-blockchain = { path = "../blockchain" }

View File

@ -260,7 +260,7 @@ impl HeaderChain {
let best_block = { let best_block = {
let era = match candidates.get(&curr.best_num) { let era = match candidates.get(&curr.best_num) {
Some(era) => era, Some(era) => era,
None => bail!("Database corrupt: highest block referenced but no data."), None => return Err("Database corrupt: highest block referenced but no data.".into()),
}; };
let best = &era.candidates[0]; let best = &era.candidates[0];
@ -582,7 +582,7 @@ impl HeaderChain {
} else { } else {
let msg = format!("header of block #{} not found in DB ; database in an \ let msg = format!("header of block #{} not found in DB ; database in an \
inconsistent state", h_num); inconsistent state", h_num);
bail!(msg); return Err(msg.into());
}; };
let decoded = header.decode().expect("decoding db value failed"); let decoded = header.decode().expect("decoding db value failed");

View File

@ -86,8 +86,7 @@ extern crate keccak_hash as hash;
extern crate triehash_ethereum as triehash; extern crate triehash_ethereum as triehash;
extern crate kvdb; extern crate kvdb;
extern crate memory_cache; extern crate memory_cache;
#[macro_use] extern crate derive_more;
extern crate error_chain;
#[cfg(test)] #[cfg(test)]
extern crate kvdb_memorydb; extern crate kvdb_memorydb;

View File

@ -66,32 +66,31 @@ pub const DEFAULT_NUM_CONSECUTIVE_FAILED_REQUESTS: usize = 1;
/// OnDemand related errors /// OnDemand related errors
pub mod error { pub mod error {
// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting`
// https://github.com/paritytech/parity-ethereum/issues/10302
#![allow(deprecated)]
use futures::sync::oneshot::Canceled; use futures::sync::oneshot::Canceled;
error_chain! { /// OnDemand Error
#[derive(Debug, derive_more::Display, derive_more::From)]
foreign_links { pub enum Error {
ChannelCanceled(Canceled) #[doc = "Canceled oneshot channel"]; /// Canceled oneshot channel
ChannelCanceled(Canceled),
/// Timeout bad response
BadResponse(String),
/// OnDemand requests limit exceeded
#[display(fmt = "OnDemand request maximum backoff iterations exceeded")]
RequestLimit,
} }
errors { impl std::error::Error for Error {
#[doc = "Timeout bad response"] fn source(&self) -> Option<&(std::error::Error + 'static)> {
BadResponse(err: String) { match self {
description("Max response evaluation time exceeded") Error::ChannelCanceled(err) => Some(err),
display("{}", err) _ => None,
}
}
} }
#[doc = "OnDemand requests limit exceeded"] /// OnDemand Result
RequestLimit { pub type Result<T> = std::result::Result<T, Error>;
description("OnDemand request maximum backoff iterations exceeded")
display("OnDemand request maximum backoff iterations exceeded")
}
}
}
} }
/// Public interface for performing network requests `OnDemand` /// Public interface for performing network requests `OnDemand`
@ -272,7 +271,7 @@ impl Pending {
response_err response_err
); );
let err = self::error::ErrorKind::BadResponse(err); let err = self::error::Error::BadResponse(err);
if self.sender.send(Err(err.into())).is_err() { if self.sender.send(Err(err.into())).is_err() {
debug!(target: "on_demand", "Dropped oneshot channel receiver on no response"); debug!(target: "on_demand", "Dropped oneshot channel receiver on no response");
} }
@ -280,7 +279,7 @@ impl Pending {
// returning a peer discovery timeout during query attempts // returning a peer discovery timeout during query attempts
fn request_limit_reached(self) { fn request_limit_reached(self) {
let err = self::error::ErrorKind::RequestLimit; let err = self::error::Error::RequestLimit;
if self.sender.send(Err(err.into())).is_err() { if self.sender.send(Err(err.into())).is_err() {
debug!(target: "on_demand", "Dropped oneshot channel receiver on time out"); debug!(target: "on_demand", "Dropped oneshot channel receiver on time out");
} }

View File

@ -16,10 +16,6 @@
//! Private transactions module. //! Private transactions module.
// Recursion limit required because of
// error_chain foreign_links.
#![recursion_limit="256"]
mod encryptor; mod encryptor;
mod key_server_keys; mod key_server_keys;
mod private_transactions; mod private_transactions;

View File

@ -5,7 +5,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
ansi_term = "0.10" ansi_term = "0.10"
error-chain = { version = "0.12", default-features = false } derive_more = "0.14.0"
ethcore = { path = ".." } ethcore = { path = ".." }
ethcore-blockchain = { path = "../blockchain" } ethcore-blockchain = { path = "../blockchain" }
ethcore-io = { path = "../../util/io" } ethcore-io = { path = "../../util/io" }

View File

@ -14,18 +14,26 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting`
// https://github.com/paritytech/parity-ethereum/issues/10302
#![allow(deprecated)]
use ethcore; use ethcore;
use io; use io;
use ethcore_private_tx; use ethcore_private_tx;
error_chain! { #[derive(Debug, derive_more::Display, derive_more::From)]
foreign_links { pub enum Error {
Ethcore(ethcore::error::Error); /// Ethcore Error
IoError(io::IoError); Ethcore(ethcore::error::Error),
PrivateTransactions(ethcore_private_tx::Error); /// Io Error
IoError(io::IoError),
/// Private Transactions Error
PrivateTransactions(ethcore_private_tx::Error),
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(std::error::Error + 'static)> {
match self {
Error::Ethcore(err) => Some(err),
Error::IoError(err) => Some(err),
Error::PrivateTransactions(err) => Some(err),
}
} }
} }

View File

@ -23,8 +23,7 @@ extern crate ethcore_sync as sync;
extern crate ethereum_types; extern crate ethereum_types;
extern crate kvdb; extern crate kvdb;
#[macro_use] extern crate derive_more;
extern crate error_chain;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
#[macro_use] #[macro_use]
@ -42,5 +41,5 @@ mod stop_guard;
#[cfg(test)] #[cfg(test)]
extern crate kvdb_rocksdb; extern crate kvdb_rocksdb;
pub use error::{Error, ErrorKind}; pub use error::Error;
pub use service::{ClientService, PrivateTxService}; pub use service::{ClientService, PrivateTxService};

View File

@ -59,7 +59,7 @@ impl PrivateTxHandler for PrivateTxService {
Ok(import_result) => Ok(import_result), Ok(import_result) => Ok(import_result),
Err(err) => { Err(err) => {
warn!(target: "privatetx", "Unable to import private transaction packet: {}", err); warn!(target: "privatetx", "Unable to import private transaction packet: {}", err);
bail!(err.to_string()) return Err(err.to_string())
} }
} }
} }
@ -69,7 +69,7 @@ impl PrivateTxHandler for PrivateTxService {
Ok(import_result) => Ok(import_result), Ok(import_result) => Ok(import_result),
Err(err) => { Err(err) => {
warn!(target: "privatetx", "Unable to import signed private transaction packet: {}", err); warn!(target: "privatetx", "Unable to import signed private transaction packet: {}", err);
bail!(err.to_string()) return Err(err.to_string())
} }
} }
} }

View File

@ -54,10 +54,6 @@
//! cargo build --release //! cargo build --release
//! ``` //! ```
// Recursion limit required because of
// error_chain foreign_links.
#![recursion_limit="128"]
extern crate ansi_term; extern crate ansi_term;
extern crate bn; extern crate bn;
extern crate byteorder; extern crate byteorder;

View File

@ -22,7 +22,7 @@ use std::time::Duration;
use bytes::Bytes; use bytes::Bytes;
use devp2p::NetworkService; use devp2p::NetworkService;
use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId, use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId,
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind, NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error,
ConnectionFilter}; ConnectionFilter};
use network::client_version::ClientVersion; use network::client_version::ClientVersion;
@ -593,7 +593,7 @@ impl ChainNotify for EthSync {
match self.network.start() { match self.network.start() {
Err((err, listen_address)) => { Err((err, listen_address)) => {
match err.into() { match err.into() {
ErrorKind::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => { Error::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => {
warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", listen_address.expect("Listen address is not set.")) warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", listen_address.expect("Listen address is not set."))
}, },
err => warn!("Error starting network: {}", err), err => warn!("Error starting network: {}", err),
@ -983,7 +983,7 @@ impl ManageNetwork for LightSync {
match self.network.start() { match self.network.start() {
Err((err, listen_address)) => { Err((err, listen_address)) => {
match err.into() { match err.into() {
ErrorKind::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => { Error::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => {
warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", listen_address.expect("Listen address is not set.")) warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", listen_address.expect("Listen address is not set."))
}, },
err => warn!("Error starting network: {}", err), err => warn!("Error starting network: {}", err),

View File

@ -435,13 +435,13 @@ impl BlockCollection {
}, },
None => { None => {
warn!("Got body with no header {}", h); warn!("Got body with no header {}", h);
Err(network::ErrorKind::BadProtocol.into()) Err(network::Error::BadProtocol)
} }
} }
} }
None => { None => {
trace!(target: "sync", "Ignored unknown/stale block body. tx_root = {:?}, uncles = {:?}", header_id.transactions_root, header_id.uncles); trace!(target: "sync", "Ignored unknown/stale block body. tx_root = {:?}, uncles = {:?}", header_id.transactions_root, header_id.uncles);
Err(network::ErrorKind::BadProtocol.into()) Err(network::Error::BadProtocol)
} }
} }
} }
@ -463,7 +463,7 @@ impl BlockCollection {
}, },
None => { None => {
warn!("Got receipt with no header {}", h); warn!("Got receipt with no header {}", h);
return Err(network::ErrorKind::BadProtocol.into()) return Err(network::Error::BadProtocol)
} }
} }
} }
@ -471,7 +471,7 @@ impl BlockCollection {
}, },
hash_map::Entry::Vacant(_) => { hash_map::Entry::Vacant(_) => {
trace!(target: "sync", "Ignored unknown/stale block receipt {:?}", receipt_root); trace!(target: "sync", "Ignored unknown/stale block receipt {:?}", receipt_root);
Err(network::ErrorKind::BadProtocol.into()) Err(network::Error::BadProtocol)
} }
} }
} }

View File

@ -76,5 +76,5 @@ mod api;
pub use api::*; pub use api::*;
pub use chain::{SyncStatus, SyncState}; pub use chain::{SyncStatus, SyncState};
pub use devp2p::validate_node_url; pub use devp2p::validate_node_url;
pub use network::{NonReservedPeerMode, Error, ErrorKind, ConnectionFilter, ConnectionDirection}; pub use network::{NonReservedPeerMode, Error, ConnectionFilter, ConnectionDirection};
pub use private_tx::{PrivateTxHandler, NoopPrivateTxHandler, SimplePrivateTxHandler}; pub use private_tx::{PrivateTxHandler, NoopPrivateTxHandler, SimplePrivateTxHandler};

View File

@ -41,8 +41,6 @@ extern crate ethabi_contract;
#[macro_use] #[macro_use]
extern crate ethabi_derive; extern crate ethabi_derive;
#[macro_use] #[macro_use]
extern crate error_chain;
#[macro_use]
extern crate log; extern crate log;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;

View File

@ -168,7 +168,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
if self.client.transaction_already_included(&hash) { if self.client.transaction_already_included(&hash) {
trace!(target: "txqueue", "[{:?}] Rejected tx already in the blockchain", hash); trace!(target: "txqueue", "[{:?}] Rejected tx already in the blockchain", hash);
bail!(transaction::Error::AlreadyImported) return Err(transaction::Error::AlreadyImported)
} }
let gas_limit = cmp::min(self.options.tx_gas_limit, self.options.block_gas_limit); let gas_limit = cmp::min(self.options.tx_gas_limit, self.options.block_gas_limit);
@ -181,7 +181,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
self.options.block_gas_limit, self.options.block_gas_limit,
self.options.tx_gas_limit, self.options.tx_gas_limit,
); );
bail!(transaction::Error::GasLimitExceeded { return Err(transaction::Error::GasLimitExceeded {
limit: gas_limit, limit: gas_limit,
got: *tx.gas(), got: *tx.gas(),
}); });
@ -196,7 +196,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
minimal_gas, minimal_gas,
); );
bail!(transaction::Error::InsufficientGas { return Err(transaction::Error::InsufficientGas {
minimal: minimal_gas, minimal: minimal_gas,
got: *tx.gas(), got: *tx.gas(),
}) })
@ -216,7 +216,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
tx.gas_price(), tx.gas_price(),
self.options.minimal_gas_price, self.options.minimal_gas_price,
); );
bail!(transaction::Error::InsufficientGasPrice { return Err(transaction::Error::InsufficientGasPrice {
minimal: self.options.minimal_gas_price, minimal: self.options.minimal_gas_price,
got: *tx.gas_price(), got: *tx.gas_price(),
}); });
@ -231,7 +231,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
tx.gas_price(), tx.gas_price(),
vtx.transaction.gas_price, vtx.transaction.gas_price,
); );
bail!(transaction::Error::InsufficientGasPrice { return Err(transaction::Error::InsufficientGasPrice {
minimal: vtx.transaction.gas_price, minimal: vtx.transaction.gas_price,
got: *tx.gas_price(), got: *tx.gas_price(),
}); });
@ -247,7 +247,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
Ok(signed) => signed.into(), Ok(signed) => signed.into(),
Err(err) => { Err(err) => {
debug!(target: "txqueue", "[{:?}] Rejected tx {:?}", hash, err); debug!(target: "txqueue", "[{:?}] Rejected tx {:?}", hash, err);
bail!(err) return Err(err)
}, },
}, },
Transaction::Local(tx) => tx, Transaction::Local(tx) => tx,
@ -256,7 +256,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
// Verify RLP payload // Verify RLP payload
if let Err(err) = self.client.decode_transaction(&transaction.rlp_bytes()) { if let Err(err) = self.client.decode_transaction(&transaction.rlp_bytes()) {
debug!(target: "txqueue", "[{:?}] Rejected transaction's rlp payload", err); debug!(target: "txqueue", "[{:?}] Rejected transaction's rlp payload", err);
bail!(err) return Err(err)
} }
let sender = transaction.sender(); let sender = transaction.sender();
@ -276,7 +276,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
transaction.gas_price, transaction.gas_price,
self.options.minimal_gas_price, self.options.minimal_gas_price,
); );
bail!(transaction::Error::InsufficientGasPrice { return Err(transaction::Error::InsufficientGasPrice {
minimal: self.options.minimal_gas_price, minimal: self.options.minimal_gas_price,
got: transaction.gas_price, got: transaction.gas_price,
}); });
@ -291,7 +291,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
"[{:?}] Rejected tx, price overflow", "[{:?}] Rejected tx, price overflow",
hash hash
); );
bail!(transaction::Error::InsufficientBalance { return Err(transaction::Error::InsufficientBalance {
cost: U256::max_value(), cost: U256::max_value(),
balance: account_details.balance, balance: account_details.balance,
}); });
@ -304,7 +304,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
account_details.balance, account_details.balance,
cost, cost,
); );
bail!(transaction::Error::InsufficientBalance { return Err(transaction::Error::InsufficientBalance {
cost: cost, cost: cost,
balance: account_details.balance, balance: account_details.balance,
}); });
@ -318,7 +318,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
transaction.nonce, transaction.nonce,
account_details.nonce, account_details.nonce,
); );
bail!(transaction::Error::Old); return Err(transaction::Error::Old);
} }
let priority = match (is_own || account_details.is_local, is_retracted) { let priority = match (is_own || account_details.is_local, is_retracted) {

View File

@ -710,7 +710,7 @@ impl Configuration {
for line in &lines { for line in &lines {
match validate_node_url(line).map(Into::into) { match validate_node_url(line).map(Into::into) {
None => continue, None => continue,
Some(sync::ErrorKind::AddressResolve(_)) => return Err(format!("Failed to resolve hostname of a boot node: {}", line)), Some(sync::Error::AddressResolve(_)) => return Err(format!("Failed to resolve hostname of a boot node: {}", line)),
Some(_) => return Err(format!("Invalid node address format given for a boot node: {}", line)), Some(_) => return Err(format!("Invalid node address format given for a boot node: {}", line)),
} }
} }

View File

@ -186,7 +186,7 @@ pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {
Some(ref x) if !x.is_empty() => x.split(',').map(|s| { Some(ref x) if !x.is_empty() => x.split(',').map(|s| {
match validate_node_url(s).map(Into::into) { match validate_node_url(s).map(Into::into) {
None => Ok(s.to_owned()), None => Ok(s.to_owned()),
Some(sync::ErrorKind::AddressResolve(_)) => Err(format!("Failed to resolve hostname of a boot node: {}", s)), Some(sync::Error::AddressResolve(_)) => Err(format!("Failed to resolve hostname of a boot node: {}", s)),
Some(_) => Err(format!("Invalid node address format given for a boot node: {}", s)), Some(_) => Err(format!("Invalid node address format given for a boot node: {}", s)),
} }
}).collect(), }).collect(),

View File

@ -25,7 +25,7 @@ use rlp::DecoderError;
use types::transaction::Error as TransactionError; use types::transaction::Error as TransactionError;
use ethcore_private_tx::Error as PrivateTransactionError; use ethcore_private_tx::Error as PrivateTransactionError;
use vm::Error as VMError; use vm::Error as VMError;
use light::on_demand::error::{Error as OnDemandError, ErrorKind as OnDemandErrorKind}; use light::on_demand::error::{Error as OnDemandError};
use ethcore::client::BlockChainClient; use ethcore::client::BlockChainClient;
use types::blockchain_info::BlockChainInfo; use types::blockchain_info::BlockChainInfo;
use v1::types::BlockNumber; use v1::types::BlockNumber;
@ -555,10 +555,9 @@ pub fn filter_block_not_found(id: BlockId) -> Error {
pub fn on_demand_error(err: OnDemandError) -> Error { pub fn on_demand_error(err: OnDemandError) -> Error {
match err { match err {
OnDemandError(OnDemandErrorKind::ChannelCanceled(e), _) => on_demand_cancel(e), OnDemandError::ChannelCanceled(e) => on_demand_cancel(e),
OnDemandError(OnDemandErrorKind::RequestLimit, _) => timeout_new_peer(&err), OnDemandError::RequestLimit => timeout_new_peer(&err),
OnDemandError(OnDemandErrorKind::BadResponse(_), _) => max_attempts_reached(&err), OnDemandError::BadResponse(_) => max_attempts_reached(&err),
_ => on_demand_others(&err),
} }
} }
@ -583,14 +582,6 @@ pub fn timeout_new_peer(err: &OnDemandError) -> Error {
} }
} }
pub fn on_demand_others(err: &OnDemandError) -> Error {
Error {
code: ErrorCode::ServerError(codes::UNKNOWN_ERROR),
message: err.to_string(),
data: None,
}
}
pub fn status_error(has_peers: bool) -> Error { pub fn status_error(has_peers: bool) -> Error {
if has_peers { if has_peers {
no_work() no_work()

View File

@ -37,7 +37,7 @@ use tiny_keccak::Keccak;
use ethkey::crypto; use ethkey::crypto;
use handshake::Handshake; use handshake::Handshake;
use io::{IoContext, StreamToken}; use io::{IoContext, StreamToken};
use network::{Error, ErrorKind}; use network::Error;
const ENCRYPTED_HEADER_LEN: usize = 32; const ENCRYPTED_HEADER_LEN: usize = 32;
const RECEIVE_PAYLOAD: Duration = Duration::from_secs(30); const RECEIVE_PAYLOAD: Duration = Duration::from_secs(30);
@ -358,7 +358,7 @@ impl EncryptedConnection {
let mut header = RlpStream::new(); let mut header = RlpStream::new();
let len = payload.len(); let len = payload.len();
if len > MAX_PAYLOAD_SIZE { if len > MAX_PAYLOAD_SIZE {
bail!(ErrorKind::OversizedPacket); return Err(Error::OversizedPacket);
} }
header.append_raw(&[(len >> 16) as u8, (len >> 8) as u8, len as u8], 1); header.append_raw(&[(len >> 16) as u8, (len >> 8) as u8, len as u8], 1);
header.append_raw(&[0xc2u8, 0x80u8, 0x80u8], 1); header.append_raw(&[0xc2u8, 0x80u8, 0x80u8], 1);
@ -386,14 +386,14 @@ impl EncryptedConnection {
/// Decrypt and authenticate an incoming packet header. Prepare for receiving payload. /// Decrypt and authenticate an incoming packet header. Prepare for receiving payload.
fn read_header(&mut self, header: &[u8]) -> Result<(), Error> { fn read_header(&mut self, header: &[u8]) -> Result<(), Error> {
if header.len() != ENCRYPTED_HEADER_LEN { if header.len() != ENCRYPTED_HEADER_LEN {
return Err(ErrorKind::Auth.into()); return Err(Error::Auth);
} }
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &header[0..16]); EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &header[0..16]);
let mac = &header[16..]; let mac = &header[16..];
let mut expected = H256::zero(); let mut expected = H256::zero();
self.ingress_mac.clone().finalize(expected.as_bytes_mut()); self.ingress_mac.clone().finalize(expected.as_bytes_mut());
if mac != &expected[0..16] { if mac != &expected[0..16] {
return Err(ErrorKind::Auth.into()); return Err(Error::Auth);
} }
let mut hdec = H128::default(); let mut hdec = H128::default();
@ -422,7 +422,7 @@ impl EncryptedConnection {
let padding = (16 - (self.payload_len % 16)) % 16; let padding = (16 - (self.payload_len % 16)) % 16;
let full_length = self.payload_len + padding + 16; let full_length = self.payload_len + padding + 16;
if payload.len() != full_length { if payload.len() != full_length {
return Err(ErrorKind::Auth.into()); return Err(Error::Auth);
} }
self.ingress_mac.update(&payload[0..payload.len() - 16]); self.ingress_mac.update(&payload[0..payload.len() - 16]);
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]); EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]);
@ -430,7 +430,7 @@ impl EncryptedConnection {
let mut expected = H128::default(); let mut expected = H128::default();
self.ingress_mac.clone().finalize(expected.as_bytes_mut()); self.ingress_mac.clone().finalize(expected.as_bytes_mut());
if mac != &expected[..] { if mac != &expected[..] {
return Err(ErrorKind::Auth.into()); return Err(Error::Auth);
} }
let mut packet = vec![0u8; self.payload_len]; let mut packet = vec![0u8; self.payload_len];

View File

@ -27,7 +27,7 @@ use parity_bytes::Bytes;
use rlp::{Rlp, RlpStream}; use rlp::{Rlp, RlpStream};
use ethkey::{KeyPair, recover, Secret, sign}; use ethkey::{KeyPair, recover, Secret, sign};
use network::{Error, ErrorKind}; use network::Error;
use network::IpFilter; use network::IpFilter;
use node_table::*; use node_table::*;
use PROTOCOL_VERSION; use PROTOCOL_VERSION;
@ -482,12 +482,12 @@ impl<'a> Discovery<'a> {
pub fn on_packet(&mut self, packet: &[u8], from: SocketAddr) -> Result<Option<TableUpdates>, Error> { pub fn on_packet(&mut self, packet: &[u8], from: SocketAddr) -> Result<Option<TableUpdates>, Error> {
// validate packet // validate packet
if packet.len() < 32 + 65 + 4 + 1 { if packet.len() < 32 + 65 + 4 + 1 {
return Err(ErrorKind::BadProtocol.into()); return Err(Error::BadProtocol);
} }
let hash_signed = keccak(&packet[32..]); let hash_signed = keccak(&packet[32..]);
if hash_signed[..] != packet[0..32] { if hash_signed[..] != packet[0..32] {
return Err(ErrorKind::BadProtocol.into()); return Err(Error::BadProtocol);
} }
let signed = &packet[(32 + 65)..]; let signed = &packet[(32 + 65)..];
@ -512,7 +512,7 @@ impl<'a> Discovery<'a> {
let secs_since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs(); let secs_since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
if self.check_timestamps && timestamp < secs_since_epoch { if self.check_timestamps && timestamp < secs_since_epoch {
debug!(target: "discovery", "Expired packet"); debug!(target: "discovery", "Expired packet");
return Err(ErrorKind::Expired.into()); return Err(Error::Expired);
} }
Ok(()) Ok(())
} }

View File

@ -28,7 +28,7 @@ use ethkey::{Generator, KeyPair, Public, Random, recover, Secret, sign};
use ethkey::crypto::{ecdh, ecies}; use ethkey::crypto::{ecdh, ecies};
use host::HostInfo; use host::HostInfo;
use io::{IoContext, StreamToken}; use io::{IoContext, StreamToken};
use network::{Error, ErrorKind}; use network::Error;
use node_table::NodeId; use node_table::NodeId;
#[derive(PartialEq, Eq, Debug)] #[derive(PartialEq, Eq, Debug)]
@ -166,7 +166,7 @@ impl Handshake {
trace!(target: "network", "Received handshake auth from {:?}", self.connection.remote_addr_str()); trace!(target: "network", "Received handshake auth from {:?}", self.connection.remote_addr_str());
if data.len() != V4_AUTH_PACKET_SIZE { if data.len() != V4_AUTH_PACKET_SIZE {
debug!(target: "network", "Wrong auth packet size"); debug!(target: "network", "Wrong auth packet size");
return Err(ErrorKind::BadProtocol.into()); return Err(Error::BadProtocol);
} }
self.auth_cipher = data.to_vec(); self.auth_cipher = data.to_vec();
match ecies::decrypt(secret, &[], data) { match ecies::decrypt(secret, &[], data) {
@ -183,7 +183,7 @@ impl Handshake {
let total = ((u16::from(data[0]) << 8 | (u16::from(data[1]))) as usize) + 2; let total = ((u16::from(data[0]) << 8 | (u16::from(data[1]))) as usize) + 2;
if total < V4_AUTH_PACKET_SIZE { if total < V4_AUTH_PACKET_SIZE {
debug!(target: "network", "Wrong EIP8 auth packet size"); debug!(target: "network", "Wrong EIP8 auth packet size");
return Err(ErrorKind::BadProtocol.into()); return Err(Error::BadProtocol);
} }
let rest = total - data.len(); let rest = total - data.len();
self.state = HandshakeState::ReadingAuthEip8; self.state = HandshakeState::ReadingAuthEip8;
@ -212,7 +212,7 @@ impl Handshake {
trace!(target: "network", "Received handshake ack from {:?}", self.connection.remote_addr_str()); trace!(target: "network", "Received handshake ack from {:?}", self.connection.remote_addr_str());
if data.len() != V4_ACK_PACKET_SIZE { if data.len() != V4_ACK_PACKET_SIZE {
debug!(target: "network", "Wrong ack packet size"); debug!(target: "network", "Wrong ack packet size");
return Err(ErrorKind::BadProtocol.into()); return Err(Error::BadProtocol);
} }
self.ack_cipher = data.to_vec(); self.ack_cipher = data.to_vec();
match ecies::decrypt(secret, &[], data) { match ecies::decrypt(secret, &[], data) {
@ -226,7 +226,7 @@ impl Handshake {
let total = (((u16::from(data[0])) << 8 | (u16::from(data[1]))) as usize) + 2; let total = (((u16::from(data[0])) << 8 | (u16::from(data[1]))) as usize) + 2;
if total < V4_ACK_PACKET_SIZE { if total < V4_ACK_PACKET_SIZE {
debug!(target: "network", "Wrong EIP8 ack packet size"); debug!(target: "network", "Wrong EIP8 ack packet size");
return Err(ErrorKind::BadProtocol.into()); return Err(Error::BadProtocol);
} }
let rest = total - data.len(); let rest = total - data.len();
self.state = HandshakeState::ReadingAckEip8; self.state = HandshakeState::ReadingAckEip8;

View File

@ -44,7 +44,7 @@ use io::*;
use ip_utils::{map_external_address, select_public_address}; use ip_utils::{map_external_address, select_public_address};
use network::{NetworkConfiguration, NetworkIoMessage, PacketId, PeerId, ProtocolId}; use network::{NetworkConfiguration, NetworkIoMessage, PacketId, PeerId, ProtocolId};
use network::{NetworkContext as NetworkContextTrait, NonReservedPeerMode}; use network::{NetworkContext as NetworkContextTrait, NonReservedPeerMode};
use network::{DisconnectReason, Error, ErrorKind, NetworkProtocolHandler, SessionInfo}; use network::{DisconnectReason, Error, NetworkProtocolHandler, SessionInfo};
use network::{ConnectionDirection, ConnectionFilter}; use network::{ConnectionDirection, ConnectionFilter};
use network::client_version::ClientVersion; use network::client_version::ClientVersion;
use node_table::*; use node_table::*;
@ -157,7 +157,7 @@ impl<'s> NetworkContextTrait for NetworkContext<'s> {
fn respond(&self, packet_id: PacketId, data: Vec<u8>) -> Result<(), Error> { fn respond(&self, packet_id: PacketId, data: Vec<u8>) -> Result<(), Error> {
assert!(self.session.is_some(), "Respond called without network context"); assert!(self.session.is_some(), "Respond called without network context");
self.session_id.map_or_else(|| Err(ErrorKind::Expired.into()), |id| self.send(id, packet_id, data)) self.session_id.map_or_else(|| Err(Error::Expired), |id| self.send(id, packet_id, data))
} }
fn disable_peer(&self, peer: PeerId) { fn disable_peer(&self, peer: PeerId) {
@ -719,8 +719,8 @@ impl Host {
Err(e) => { Err(e) => {
let s = session.lock(); let s = session.lock();
trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e); trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e);
match *e.kind() { match e {
ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) | ErrorKind::Disconnect(DisconnectReason::UselessPeer) => { Error::Disconnect(DisconnectReason::IncompatibleProtocol) | Error::Disconnect(DisconnectReason::UselessPeer) => {
if let Some(id) = s.id() { if let Some(id) = s.id() {
if !self.reserved_nodes.read().contains(id) { if !self.reserved_nodes.read().contains(id) {
let mut nodes = self.nodes.write(); let mut nodes = self.nodes.write();

View File

@ -68,8 +68,6 @@ extern crate bytes;
extern crate crypto as rcrypto; extern crate crypto as rcrypto;
#[cfg(test)] #[cfg(test)]
extern crate env_logger; extern crate env_logger;
#[macro_use]
extern crate error_chain;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore_network as network; extern crate ethcore_network as network;
extern crate ethereum_types; extern crate ethereum_types;

View File

@ -31,7 +31,7 @@ use serde_json;
use discovery::{NodeEntry, TableUpdates}; use discovery::{NodeEntry, TableUpdates};
use ip_utils::*; use ip_utils::*;
use network::{AllowIP, Error, ErrorKind, IpFilter}; use network::{AllowIP, Error, IpFilter};
/// Node public key /// Node public key
pub type NodeId = H512; pub type NodeId = H512;
@ -133,8 +133,8 @@ impl FromStr for NodeEndpoint {
address: a, address: a,
udp_port: a.port() udp_port: a.port()
}), }),
Ok(None) => bail!(ErrorKind::AddressResolve(None)), Ok(None) => return Err(Error::AddressResolve(None.into())),
Err(_) => Err(ErrorKind::AddressParse.into()) // always an io::Error of InvalidInput kind Err(_) => Err(Error::AddressParse) // always an io::Error of InvalidInput kind
} }
} }
} }
@ -216,7 +216,7 @@ impl FromStr for Node {
type Err = Error; type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let (id, endpoint) = if s.len() > 136 && &s[0..8] == "enode://" && &s[136..137] == "@" { let (id, endpoint) = if s.len() > 136 && &s[0..8] == "enode://" && &s[136..137] == "@" {
(s[8..136].parse().map_err(|_| ErrorKind::InvalidNodeId)?, NodeEndpoint::from_str(&s[137..])?) (s[8..136].parse().map_err(|_| Error::InvalidNodeId)?, NodeEndpoint::from_str(&s[137..])?)
} }
else { else {
(NodeId::default(), NodeEndpoint::from_str(s)?) (NodeId::default(), NodeEndpoint::from_str(s)?)
@ -629,21 +629,21 @@ mod tests {
fn endpoint_parse_empty_ip_string_returns_error() { fn endpoint_parse_empty_ip_string_returns_error() {
let endpoint = NodeEndpoint::from_str(""); let endpoint = NodeEndpoint::from_str("");
assert!(endpoint.is_err()); assert!(endpoint.is_err());
assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse); assert_matches!(endpoint.unwrap_err(), Error::AddressParse);
} }
#[test] #[test]
fn endpoint_parse_invalid_ip_string_returns_error() { fn endpoint_parse_invalid_ip_string_returns_error() {
let endpoint = NodeEndpoint::from_str("beef"); let endpoint = NodeEndpoint::from_str("beef");
assert!(endpoint.is_err()); assert!(endpoint.is_err());
assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse); assert_matches!(endpoint.unwrap_err(), Error::AddressParse);
} }
#[test] #[test]
fn endpoint_parse_valid_ip_without_port_returns_error() { fn endpoint_parse_valid_ip_without_port_returns_error() {
let endpoint = NodeEndpoint::from_str("123.123.123.123"); let endpoint = NodeEndpoint::from_str("123.123.123.123");
assert!(endpoint.is_err()); assert!(endpoint.is_err());
assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse); assert_matches!(endpoint.unwrap_err(), Error::AddressParse);
let endpoint = NodeEndpoint::from_str("123.123.123.123:123"); let endpoint = NodeEndpoint::from_str("123.123.123.123:123");
assert!(endpoint.is_ok()) assert!(endpoint.is_ok())
} }
@ -668,11 +668,11 @@ mod tests {
fn node_parse_fails_for_invalid_urls() { fn node_parse_fails_for_invalid_urls() {
let node = Node::from_str("foo"); let node = Node::from_str("foo");
assert!(node.is_err()); assert!(node.is_err());
assert_matches!(node.unwrap_err().kind(), &ErrorKind::AddressParse); assert_matches!(node.unwrap_err(), Error::AddressParse);
let node = Node::from_str("enode://foo@bar"); let node = Node::from_str("enode://foo@bar");
assert!(node.is_err()); assert!(node.is_err());
assert_matches!(node.unwrap_err().kind(), &ErrorKind::AddressParse); assert_matches!(node.unwrap_err(), Error::AddressParse);
} }
#[test] #[test]

View File

@ -30,7 +30,7 @@ use connection::{Connection, EncryptedConnection, MAX_PAYLOAD_SIZE, Packet};
use handshake::Handshake; use handshake::Handshake;
use host::*; use host::*;
use io::{IoContext, StreamToken}; use io::{IoContext, StreamToken};
use network::{DisconnectReason, Error, ErrorKind, PeerCapabilityInfo, ProtocolId, SessionInfo}; use network::{DisconnectReason, Error, PeerCapabilityInfo, ProtocolId, SessionInfo};
use network::client_version::ClientVersion; use network::client_version::ClientVersion;
use network::SessionCapabilityInfo; use network::SessionCapabilityInfo;
use node_table::NodeId; use node_table::NodeId;
@ -256,10 +256,10 @@ impl Session {
where Message: Send + Sync + Clone { where Message: Send + Sync + Clone {
if protocol.is_some() && (self.info.capabilities.is_empty() || !self.had_hello) { if protocol.is_some() && (self.info.capabilities.is_empty() || !self.had_hello) {
debug!(target: "network", "Sending to unconfirmed session {}, protocol: {:?}, packet: {}", self.token(), protocol.as_ref().map(|p| str::from_utf8(&p[..]).unwrap_or("??")), packet_id); debug!(target: "network", "Sending to unconfirmed session {}, protocol: {:?}, packet: {}", self.token(), protocol.as_ref().map(|p| str::from_utf8(&p[..]).unwrap_or("??")), packet_id);
bail!(ErrorKind::BadProtocol); return Err(Error::BadProtocol);
} }
if self.expired() { if self.expired() {
return Err(ErrorKind::Expired.into()); return Err(Error::Expired);
} }
let mut i = 0usize; let mut i = 0usize;
let pid = match protocol { let pid = match protocol {
@ -281,7 +281,7 @@ impl Session {
let mut payload = data; // create a reference with local lifetime let mut payload = data; // create a reference with local lifetime
if self.compression { if self.compression {
if payload.len() > MAX_PAYLOAD_SIZE { if payload.len() > MAX_PAYLOAD_SIZE {
bail!(ErrorKind::OversizedPacket); return Err(Error::OversizedPacket);
} }
let len = snappy::compress_into(&payload, &mut compressed); let len = snappy::compress_into(&payload, &mut compressed);
trace!(target: "network", "compressed {} to {}", payload.len(), len); trace!(target: "network", "compressed {} to {}", payload.len(), len);
@ -331,16 +331,16 @@ impl Session {
fn read_packet<Message>(&mut self, io: &IoContext<Message>, packet: &Packet, host: &HostInfo) -> Result<SessionData, Error> fn read_packet<Message>(&mut self, io: &IoContext<Message>, packet: &Packet, host: &HostInfo) -> Result<SessionData, Error>
where Message: Send + Sync + Clone { where Message: Send + Sync + Clone {
if packet.data.len() < 2 { if packet.data.len() < 2 {
return Err(ErrorKind::BadProtocol.into()); return Err(Error::BadProtocol);
} }
let packet_id = packet.data[0]; let packet_id = packet.data[0];
if packet_id != PACKET_HELLO && packet_id != PACKET_DISCONNECT && !self.had_hello { if packet_id != PACKET_HELLO && packet_id != PACKET_DISCONNECT && !self.had_hello {
return Err(ErrorKind::BadProtocol.into()); return Err(Error::BadProtocol);
} }
let data = if self.compression { let data = if self.compression {
let compressed = &packet.data[1..]; let compressed = &packet.data[1..];
if snappy::decompressed_len(&compressed)? > MAX_PAYLOAD_SIZE { if snappy::decompressed_len(&compressed)? > MAX_PAYLOAD_SIZE {
bail!(ErrorKind::OversizedPacket); return Err(Error::OversizedPacket);
} }
snappy::decompress(&compressed)? snappy::decompress(&compressed)?
} else { } else {
@ -358,7 +358,7 @@ impl Session {
if self.had_hello { if self.had_hello {
debug!(target:"network", "Disconnected: {}: {:?}", self.token(), DisconnectReason::from_u8(reason)); debug!(target:"network", "Disconnected: {}: {:?}", self.token(), DisconnectReason::from_u8(reason));
} }
Err(ErrorKind::Disconnect(DisconnectReason::from_u8(reason)).into()) Err(Error::Disconnect(DisconnectReason::from_u8(reason)))
} }
PACKET_PING => { PACKET_PING => {
self.send_pong(io)?; self.send_pong(io)?;
@ -500,7 +500,7 @@ impl Session {
rlp.append(&(reason as u32)); rlp.append(&(reason as u32));
self.send_packet(io, None, PACKET_DISCONNECT, &rlp.drain()).ok(); self.send_packet(io, None, PACKET_DISCONNECT, &rlp.drain()).ok();
} }
ErrorKind::Disconnect(reason).into() Error::Disconnect(reason)
} }
fn send<Message>(&mut self, io: &IoContext<Message>, data: &[u8]) -> Result<(), Error> where Message: Send + Sync + Clone { fn send<Message>(&mut self, io: &IoContext<Message>, data: &[u8]) -> Result<(), Error> where Message: Send + Sync + Clone {

View File

@ -7,7 +7,7 @@ version = "1.12.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
error-chain = { version = "0.12", default-features = false } derive_more = "0.14.0"
parity-crypto = "0.4.0" parity-crypto = "0.4.0"
ethcore-io = { path = "../io" } ethcore-io = { path = "../io" }
ethereum-types = "0.6.0" ethereum-types = "0.6.0"

View File

@ -14,11 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting` use std::{error, io, net, fmt};
// https://github.com/paritytech/parity-ethereum/issues/10302
#![allow(deprecated)]
use std::{io, net, fmt};
use libc::{ENFILE, EMFILE}; use libc::{ENFILE, EMFILE};
use io::IoError; use io::IoError;
use {rlp, ethkey, crypto, snappy}; use {rlp, ethkey, crypto, snappy};
@ -85,118 +81,127 @@ impl fmt::Display for DisconnectReason {
} }
} }
error_chain! { /// Queue error
foreign_links { #[derive(Debug, derive_more::Display)]
SocketIo(IoError) #[doc = "Socket IO error."]; pub enum Error {
Decompression(snappy::InvalidInput) #[doc = "Decompression error."]; /// Socket IO error.
Rlp(rlp::DecoderError) #[doc = "Rlp decoder error."]; SocketIo(IoError),
} /// Decompression error.
Decompression(snappy::InvalidInput),
/// Rlp decoder error.
Rlp(rlp::DecoderError),
/// Error concerning the network address parsing subsystem.
#[display(fmt = "Failed to parse network address")]
AddressParse,
/// Error concerning the network address resolution subsystem.
#[display(fmt = "Failed to resolve network address {}", _0)]
AddressResolve(AddressResolveError),
/// Authentication failure
#[display(fmt = "Authentication failure")]
Auth,
/// Unrecognised protocol
#[display(fmt = "Bad protocol")]
BadProtocol,
/// Expired message
#[display(fmt = "Expired message")]
Expired,
/// Peer not found
#[display(fmt = "Peer not found")]
PeerNotFound,
/// Peer is disconnected
#[display(fmt = "Peer disconnected: {}", _0)]
Disconnect(DisconnectReason),
/// Invalid node id
#[display(fmt = "Invalid node id")]
InvalidNodeId,
/// Packet size is over the protocol limit
#[display(fmt = "Packet is too large")]
OversizedPacket,
/// Reached system resource limits for this process
#[display(fmt = "Too many open files in this process. Check your resource limits and restart parity")]
ProcessTooManyFiles,
/// Reached system wide resource limits
#[display(fmt = "Too many open files on system. Consider closing some processes/release some file handlers or increas the system-wide resource limits and restart parity.")]
SystemTooManyFiles,
/// An unknown IO error occurred.
#[display(fmt = "Unexpected IO error: {}", _0)]
Io(io::Error),
}
errors { /// Wraps io::Error for Display impl
#[doc = "Error concerning the network address parsing subsystem."] #[derive(Debug)]
AddressParse { pub struct AddressResolveError(Option<io::Error>);
description("Failed to parse network address"),
display("Failed to parse network address"),
}
#[doc = "Error concerning the network address resolution subsystem."] impl fmt::Display for AddressResolveError {
AddressResolve(err: Option<io::Error>) { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
description("Failed to resolve network address"), write!(f, "{}", self.0.as_ref().map_or("".to_string(), |e| e.to_string()))
display("Failed to resolve network address {}", err.as_ref().map_or("".to_string(), |e| e.to_string())),
} }
}
#[doc = "Authentication failure"] impl From<Option<io::Error>> for AddressResolveError {
Auth { fn from(err: Option<io::Error>) -> Self {
description("Authentication failure"), AddressResolveError(err)
display("Authentication failure"),
} }
}
#[doc = "Unrecognised protocol"] impl error::Error for Error {
BadProtocol { fn source(&self) -> Option<&(error::Error + 'static)> {
description("Bad protocol"), match self {
display("Bad protocol"), Error::Decompression(e) => Some(e),
Error::Rlp(e) => Some(e),
_ => None,
} }
}
}
#[doc = "Expired message"] impl From<IoError> for Error {
Expired { fn from(err: IoError) -> Self {
description("Expired message"), Error::SocketIo(err)
display("Expired message"),
} }
}
#[doc = "Peer not found"] impl From<snappy::InvalidInput> for Error {
PeerNotFound { fn from(err: snappy::InvalidInput) -> Self {
description("Peer not found"), Error::Decompression(err)
display("Peer not found"),
} }
}
#[doc = "Peer is disconnected"] impl From<rlp::DecoderError> for Error {
Disconnect(reason: DisconnectReason) { fn from(err: rlp::DecoderError) -> Self {
description("Peer disconnected"), Error::Rlp(err)
display("Peer disconnected: {}", reason),
}
#[doc = "Invalid node id"]
InvalidNodeId {
description("Invalid node id"),
display("Invalid node id"),
}
#[doc = "Packet size is over the protocol limit"]
OversizedPacket {
description("Packet is too large"),
display("Packet is too large"),
}
#[doc = "Reached system resource limits for this process"]
ProcessTooManyFiles {
description("Too many open files in process."),
display("Too many open files in this process. Check your resource limits and restart parity"),
}
#[doc = "Reached system wide resource limits"]
SystemTooManyFiles {
description("Too many open files on system."),
display("Too many open files on system. Consider closing some processes/release some file handlers or increas the system-wide resource limits and restart parity."),
}
#[doc = "An unknown IO error occurred."]
Io(err: io::Error) {
description("IO Error"),
display("Unexpected IO error: {}", err),
}
} }
} }
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(err: io::Error) -> Self { fn from(err: io::Error) -> Self {
match err.raw_os_error() { match err.raw_os_error() {
Some(ENFILE) => ErrorKind::ProcessTooManyFiles.into(), Some(ENFILE) => Error::ProcessTooManyFiles,
Some(EMFILE) => ErrorKind::SystemTooManyFiles.into(), Some(EMFILE) => Error::SystemTooManyFiles,
_ => Error::from_kind(ErrorKind::Io(err)) _ => Error::Io(err)
} }
} }
} }
impl From<ethkey::Error> for Error { impl From<ethkey::Error> for Error {
fn from(_err: ethkey::Error) -> Self { fn from(_err: ethkey::Error) -> Self {
ErrorKind::Auth.into() Error::Auth
} }
} }
impl From<ethkey::crypto::Error> for Error { impl From<ethkey::crypto::Error> for Error {
fn from(_err: ethkey::crypto::Error) -> Self { fn from(_err: ethkey::crypto::Error) -> Self {
ErrorKind::Auth.into() Error::Auth
} }
} }
impl From<crypto::error::SymmError> for Error { impl From<crypto::error::SymmError> for Error {
fn from(_err: crypto::error::SymmError) -> Self { fn from(_err: crypto::error::SymmError) -> Self {
ErrorKind::Auth.into() Error::Auth
} }
} }
impl From<net::AddrParseError> for Error { impl From<net::AddrParseError> for Error {
fn from(_err: net::AddrParseError) -> Self { ErrorKind::AddressParse.into() } fn from(_err: net::AddrParseError) -> Self { Error::AddressParse }
} }
#[test] #[test]
@ -208,13 +213,13 @@ fn test_errors() {
} }
assert_eq!(DisconnectReason::Unknown, r); assert_eq!(DisconnectReason::Unknown, r);
match *<Error as From<rlp::DecoderError>>::from(rlp::DecoderError::RlpIsTooBig).kind() { match <Error as From<rlp::DecoderError>>::from(rlp::DecoderError::RlpIsTooBig) {
ErrorKind::Rlp(_) => {}, Error::Rlp(_) => {},
_ => panic!("Unexpected error"), _ => panic!("Unexpected error"),
} }
match *<Error as From<ethkey::crypto::Error>>::from(ethkey::crypto::Error::InvalidMessage).kind() { match <Error as From<ethkey::crypto::Error>>::from(ethkey::crypto::Error::InvalidMessage) {
ErrorKind::Auth => {}, Error::Auth => {},
_ => panic!("Unexpected error"), _ => panic!("Unexpected error"),
} }
} }
@ -226,18 +231,18 @@ fn test_io_errors() {
assert_matches!( assert_matches!(
<Error as From<io::Error>>::from( <Error as From<io::Error>>::from(
io::Error::from_raw_os_error(ENFILE) io::Error::from_raw_os_error(ENFILE)
).kind(), ),
ErrorKind::ProcessTooManyFiles); Error::ProcessTooManyFiles);
assert_matches!( assert_matches!(
<Error as From<io::Error>>::from( <Error as From<io::Error>>::from(
io::Error::from_raw_os_error(EMFILE) io::Error::from_raw_os_error(EMFILE)
).kind(), ),
ErrorKind::SystemTooManyFiles); Error::SystemTooManyFiles);
assert_matches!( assert_matches!(
<Error as From<io::Error>>::from( <Error as From<io::Error>>::from(
io::Error::from_raw_os_error(0) io::Error::from_raw_os_error(0)
).kind(), ),
ErrorKind::Io(_)); Error::Io(_));
} }

View File

@ -32,9 +32,7 @@ extern crate serde_derive;
#[cfg(test)] #[macro_use] #[cfg(test)] #[macro_use]
extern crate assert_matches; extern crate assert_matches;
extern crate derive_more;
#[macro_use]
extern crate error_chain;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
@ -46,7 +44,7 @@ mod error;
pub use connection_filter::{ConnectionFilter, ConnectionDirection}; pub use connection_filter::{ConnectionFilter, ConnectionDirection};
pub use io::TimerToken; pub use io::TimerToken;
pub use error::{Error, ErrorKind, DisconnectReason}; pub use error::{Error, DisconnectReason};
use client_version::ClientVersion; use client_version::ClientVersion;
use std::cmp::Ordering; use std::cmp::Ordering;