Merge pull request #6461 from paritytech/util_error_chain

UtilError utilizes error_chain!
This commit is contained in:
Marek Kotewicz 2017-09-05 16:20:19 +02:00 committed by GitHub
commit b6a1e29d11
28 changed files with 142 additions and 144 deletions

15
Cargo.lock generated
View File

@ -455,6 +455,14 @@ dependencies = [
"backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "error-chain"
version = "0.11.0-rc.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "eth-secp256k1"
version = "0.5.6"
@ -547,6 +555,7 @@ dependencies = [
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"triehash 0.1.0",
"unexpected 0.1.0",
"using_queue 0.1.0",
"vm 0.1.0",
"wasm 0.1.0",
@ -796,6 +805,7 @@ dependencies = [
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
"eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)",
"ethcore-bigint 0.1.3",
"ethcore-bloom-journal 0.1.0",
@ -3144,6 +3154,10 @@ name = "typeable"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unexpected"
version = "0.1.0"
[[package]]
name = "unicase"
version = "1.4.0"
@ -3395,6 +3409,7 @@ dependencies = [
"checksum either 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2b503c86dad62aaf414ecf2b8c527439abedb3f8d812537f0b12bfd6f32a91"
"checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85"
"checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
"checksum error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)" = "38d3a55d9a7a456748f2a3912c0941a5d9a68006eb15b3c3c9836b8420dc102d"
"checksum error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143"
"checksum eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
"checksum ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3d62319ee0f35abf20afe8859dd2668195912614346447bb2dee9fb8da7c62"

View File

@ -66,6 +66,7 @@ wasm = { path = "wasm" }
hash = { path = "../util/hash" }
triehash = { path = "../util/triehash" }
semantic_version = { path = "../util/semantic_version" }
unexpected = { path = "../util/unexpected" }
[dev-dependencies]
native-contracts = { path = "native_contracts", features = ["test_contracts"] }

View File

@ -26,7 +26,7 @@ use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError};
use bigint::prelude::U256;
use bigint::hash::H256;
use util::{Bytes, Address};
use util::error::{Mismatch, OutOfBounds};
use unexpected::{Mismatch, OutOfBounds};
use basic_types::{LogBloom, Seal};
use vm::{EnvInfo, LastHashes};

View File

@ -25,6 +25,7 @@ use itertools::Itertools;
// util
use hash::keccak;
use timer::PerfTimer;
use util::UtilError;
use util::Bytes;
use util::{journaldb, DBValue, TrieFactory, Trie};
use util::Address;
@ -252,7 +253,7 @@ impl Client {
last_hashes: RwLock::new(VecDeque::new()),
factories: factories,
history: history,
rng: Mutex::new(OsRng::new().map_err(::util::UtilError::StdIo)?),
rng: Mutex::new(OsRng::new().map_err(UtilError::from)?),
ancient_verifier: Mutex::new(None),
on_user_defaults_change: Mutex::new(None),
registrar: Mutex::new(None),

View File

@ -46,6 +46,7 @@ use bigint::prelude::{U256, U128};
use bigint::hash::{H256, H520};
use semantic_version::SemanticVersion;
use parking_lot::{Mutex, RwLock};
use unexpected::{Mismatch, OutOfBounds};
use util::*;
mod finality;

View File

@ -23,6 +23,7 @@ use bigint::prelude::U256;
use bigint::hash::{H256, H520};
use parking_lot::RwLock;
use util::*;
use unexpected::{Mismatch, OutOfBounds};
use ethkey::{recover, public_to_address, Signature};
use account_provider::AccountProvider;
use block::*;

View File

@ -58,6 +58,7 @@ use bigint::prelude::U256;
use bigint::hash::H256;
use semantic_version::SemanticVersion;
use util::*;
use unexpected::{Mismatch, OutOfBounds};
/// Default EIP-210 contrat code.
/// As defined in https://github.com/ethereum/EIPs/pull/210/commits/9df24a3714af42e3bf350265bdc75b486c909d7f#diff-e02a92c2fb96c1a1bfb05e4c6e2ef5daR49

View File

@ -34,6 +34,7 @@ use bigint::prelude::{U128, U256};
use bigint::hash::{H256, H520};
use parking_lot::RwLock;
use util::*;
use unexpected::{OutOfBounds, Mismatch};
use client::{Client, EngineClient};
use error::{Error, BlockError};
use header::{Header, BlockNumber};

View File

@ -26,6 +26,7 @@ use bigint::hash::{H160, H256};
use parking_lot::RwLock;
use util::*;
use util::cache::MemoryLruCache;
use unexpected::Mismatch;
use rlp::{UntrustedRlp, RlpStream};
use basic_types::LogBloom;

View File

@ -20,6 +20,7 @@ use std::fmt;
use bigint::prelude::U256;
use bigint::hash::H256;
use util::*;
use unexpected::{Mismatch, OutOfBounds};
use io::*;
use header::BlockNumber;
use basic_types::LogBloom;
@ -394,7 +395,7 @@ impl From<ExecutionError> for Error {
impl From<::rlp::DecoderError> for Error {
fn from(err: ::rlp::DecoderError) -> Error {
Error::Util(UtilError::Decoder(err))
Error::Util(UtilError::from(err))
}
}
@ -427,7 +428,7 @@ impl From<BlockImportError> for Error {
match err {
BlockImportError::Block(e) => Error::Block(e),
BlockImportError::Import(e) => Error::Import(e),
BlockImportError::Other(s) => Error::Util(UtilError::SimpleString(s)),
BlockImportError::Other(s) => Error::Util(UtilError::from(s)),
}
}
}

View File

@ -23,6 +23,7 @@ use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager};
use bigint::prelude::U256;
use bigint::hash::{H256, H64};
use util::*;
use unexpected::{OutOfBounds, Mismatch};
use block::*;
use builtin::Builtin;
use vm::EnvInfo;

View File

@ -108,6 +108,7 @@ extern crate heapsize;
extern crate triehash;
extern crate ansi_term;
extern crate semantic_version;
extern crate unexpected;
#[macro_use]
extern crate rlp_derive;

View File

@ -102,7 +102,7 @@ impl Restoration {
let block_chunks = manifest.block_hashes.iter().cloned().collect();
let raw_db = Arc::new(Database::open(params.db_config, &*params.db_path.to_string_lossy())
.map_err(UtilError::SimpleString)?);
.map_err(UtilError::from)?);
let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone());
let components = params.engine.snapshot_components()
@ -519,7 +519,7 @@ impl Service {
match is_done {
true => {
db.flush().map_err(::util::UtilError::SimpleString)?;
db.flush().map_err(UtilError::from)?;
drop(db);
return self.finalize_restoration(&mut *restoration);
},
@ -532,7 +532,7 @@ impl Service {
}
}
};
result.and_then(|_| db.flush().map_err(|e| ::util::UtilError::SimpleString(e).into()))
result.and_then(|_| db.flush().map_err(|e| UtilError::from(e).into()))
}
/// Feed a state chunk to be processed synchronously.

View File

@ -380,7 +380,7 @@ impl UnverifiedTransaction {
self.recover_public()?;
}
if self.gas < U256::from(self.gas_required(&schedule)) {
return Err(TransactionError::InvalidGasLimit(::util::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into())
return Err(TransactionError::InvalidGasLimit(::unexpected::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into())
}
Ok(self)
}

View File

@ -27,6 +27,7 @@ use triehash::ordered_trie_root;
use heapsize::HeapSizeOf;
use bigint::hash::H256;
use util::*;
use unexpected::{Mismatch, OutOfBounds};
use engines::Engine;
use error::{BlockError, Error};
use blockchain::*;
@ -274,6 +275,7 @@ mod tests {
use bigint::prelude::U256;
use bigint::hash::{H256, H2048};
use triehash::ordered_trie_root;
use unexpected::{Mismatch, OutOfBounds};
use util::*;
use ethkey::{Random, Generator};
use header::*;

View File

@ -34,6 +34,7 @@ regex = "0.2"
lru-cache = "0.1.0"
ethcore-logger = { path = "../logger" }
triehash = { path = "triehash" }
error-chain = "0.11.0-rc.2"
[features]
default = []

View File

@ -16,7 +16,6 @@
use io::IoError;
use rlp::*;
use util::UtilError;
use std::fmt;
use ethkey::Error as KeyError;
use crypto::Error as CryptoError;
@ -96,8 +95,8 @@ pub enum NetworkError {
PeerNotFound,
/// Peer is diconnected.
Disconnect(DisconnectReason),
/// Util error.
Util(UtilError),
/// Invalid NodeId
InvalidNodeId,
/// Socket IO error.
Io(IoError),
/// Error concerning the network address parsing subsystem.
@ -125,7 +124,7 @@ impl fmt::Display for NetworkError {
AddressResolve(Some(ref err)) => format!("{}", err),
AddressResolve(_) => "Failed to resolve network address.".into(),
StdIo(ref err) => format!("{}", err),
Util(ref err) => format!("{}", err),
InvalidNodeId => "Invalid node id".into(),
OversizedPacket => "Packet is too large".into(),
};
@ -151,12 +150,6 @@ impl From<IoError> for NetworkError {
}
}
impl From<UtilError> for NetworkError {
fn from(err: UtilError) -> NetworkError {
NetworkError::Util(err)
}
}
impl From<KeyError> for NetworkError {
fn from(_err: KeyError) -> Self {
NetworkError::Auth

View File

@ -26,7 +26,6 @@ use std::fmt;
use std::fs;
use std::io::{Read, Write};
use bigint::hash::*;
use util::UtilError;
use rlp::*;
use time::Tm;
use error::NetworkError;
@ -175,7 +174,7 @@ impl FromStr for Node {
type Err = NetworkError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (id, endpoint) = if s.len() > 136 && &s[0..8] == "enode://" && &s[136..137] == "@" {
(s[8..136].parse().map_err(UtilError::from)?, NodeEndpoint::from_str(&s[137..])?)
(s[8..136].parse().map_err(|_| NetworkError::InvalidNodeId)?, NodeEndpoint::from_str(&s[137..])?)
}
else {
(NodeId::new(), NodeEndpoint::from_str(s)?)

View File

@ -16,9 +16,12 @@
//! General error types for use in ethcore.
#![allow(missing_docs)]
#![allow(unknown_lints)]
use std::{self, fmt};
use rustc_hex::FromHexError;
use rlp::DecoderError;
use std::fmt;
use bigint::hash::H256;
#[derive(Debug)]
@ -41,124 +44,23 @@ impl fmt::Display for BaseDataError {
}
}
#[derive(Debug)]
/// General error type which should be capable of representing all errors in ethcore.
pub enum UtilError {
/// Error concerning the Rust standard library's IO subsystem.
StdIo(::std::io::Error),
/// Error concerning the hex conversion logic.
FromHex(FromHexError),
/// Error concerning the database abstraction logic.
BaseData(BaseDataError),
/// Error concerning the RLP decoder.
Decoder(DecoderError),
/// Miscellaneous error described by a string.
SimpleString(String),
/// Error from a bad input size being given for the needed output.
BadSize,
/// Error from snappy.
Snappy(::snappy::InvalidInput),
}
impl fmt::Display for UtilError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
UtilError::StdIo(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::FromHex(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::BaseData(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::Decoder(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::SimpleString(ref msg) => f.write_str(msg),
UtilError::BadSize => f.write_str("Bad input size."),
UtilError::Snappy(ref err) => f.write_fmt(format_args!("{}", err)),
}
impl std::error::Error for BaseDataError {
fn description(&self) -> &str {
"Error in database subsystem"
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
/// Error indicating an expected value was not found.
pub struct Mismatch<T: fmt::Debug> {
/// Value expected.
pub expected: T,
/// Value found.
pub found: T,
}
error_chain! {
types {
UtilError, ErrorKind, ResultExt, Result;
}
impl<T: fmt::Debug + fmt::Display> fmt::Display for Mismatch<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!("Expected {}, found {}", self.expected, self.found))
foreign_links {
Io(::std::io::Error);
FromHex(FromHexError);
Decoder(DecoderError);
Snappy(::snappy::InvalidInput);
BaseData(BaseDataError);
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
/// Error indicating value found is outside of a valid range.
pub struct OutOfBounds<T: fmt::Debug> {
/// Minimum allowed value.
pub min: Option<T>,
/// Maximum allowed value.
pub max: Option<T>,
/// Value found.
pub found: T,
}
impl<T: fmt::Debug + fmt::Display> fmt::Display for OutOfBounds<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match (self.min.as_ref(), self.max.as_ref()) {
(Some(min), Some(max)) => format!("Min={}, Max={}", min, max),
(Some(min), _) => format!("Min={}", min),
(_, Some(max)) => format!("Max={}", max),
(None, None) => "".into(),
};
f.write_fmt(format_args!("Value {} out of bounds. {}", self.found, msg))
}
}
impl From<FromHexError> for UtilError {
fn from(err: FromHexError) -> UtilError {
UtilError::FromHex(err)
}
}
impl From<BaseDataError> for UtilError {
fn from(err: BaseDataError) -> UtilError {
UtilError::BaseData(err)
}
}
impl From<::std::io::Error> for UtilError {
fn from(err: ::std::io::Error) -> UtilError {
UtilError::StdIo(err)
}
}
impl From<::rlp::DecoderError> for UtilError {
fn from(err: ::rlp::DecoderError) -> UtilError {
UtilError::Decoder(err)
}
}
impl From<String> for UtilError {
fn from(err: String) -> UtilError {
UtilError::SimpleString(err)
}
}
impl From<::snappy::InvalidInput> for UtilError {
fn from(err: ::snappy::InvalidInput) -> UtilError {
UtilError::Snappy(err)
}
}
// TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted.
/*#![feature(concat_idents)]
macro_rules! assimilate {
($name:ident) => (
impl From<concat_idents!($name, Error)> for Error {
fn from(err: concat_idents!($name, Error)) -> Error {
Error:: $name (err)
}
}
)
}
assimilate!(FromHex);
assimilate!(BaseData);*/

View File

@ -26,7 +26,8 @@ use super::{DB_PREFIX_LEN, LATEST_ERA_KEY};
use super::traits::JournalDB;
use kvdb::{KeyValueDB, DBTransaction};
use bigint::hash::H256;
use {Bytes, BaseDataError, UtilError};
use error::{BaseDataError, UtilError};
use {Bytes};
/// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay
/// and latent-removal semantics.

View File

@ -29,7 +29,8 @@ use super::{DB_PREFIX_LEN, LATEST_ERA_KEY};
use super::traits::JournalDB;
use kvdb::{KeyValueDB, DBTransaction};
use bigint::hash::H256;
use { BaseDataError, UtilError, Bytes};
use error::{BaseDataError, UtilError};
use {Bytes};
#[derive(Clone, PartialEq, Eq)]
struct RefInfo {

View File

@ -28,7 +28,8 @@ use super::{DB_PREFIX_LEN, LATEST_ERA_KEY};
use kvdb::{KeyValueDB, DBTransaction};
use super::JournalDB;
use bigint::hash::{H256, H256FastMap};
use {BaseDataError, UtilError, Bytes};
use error::{BaseDataError, UtilError};
use {Bytes};
/// Implementation of the `JournalDB` trait for a disk-backed database with a memory overlay
/// and, possibly, latent-removal semantics.

View File

@ -279,7 +279,7 @@ impl KeyValueDB for InMemory {
}
fn restore(&self, _new_db: &str) -> Result<(), UtilError> {
Err(UtilError::SimpleString("Attempted to restore in-memory database".into()))
Err("Attempted to restore in-memory database".into())
}
}

View File

@ -109,6 +109,9 @@ extern crate heapsize;
extern crate ethcore_logger;
extern crate hash as keccak;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate log as rlog;
@ -136,7 +139,7 @@ pub use overlaydb::*;
pub use journaldb::JournalDB;
pub use trie::{Trie, TrieMut, TrieDB, TrieDBMut, TrieFactory, TrieError, SecTrieDB, SecTrieDBMut};
pub use kvdb::*;
pub use error::*;
pub use error::UtilError;
pub use bytes::*;
/// 160-bit integer representing account address

View File

@ -19,7 +19,7 @@
use std::sync::Arc;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use error::*;
use error::{Result, BaseDataError};
use bigint::hash::*;
use rlp::*;
use hashdb::*;
@ -56,14 +56,14 @@ impl OverlayDB {
/// Commit all operations in a single batch.
#[cfg(test)]
pub fn commit(&mut self) -> Result<u32, UtilError> {
pub fn commit(&mut self) -> Result<u32> {
let mut batch = self.backing.transaction();
let res = self.commit_to_batch(&mut batch)?;
self.backing.write(batch).map(|_| res).map_err(|e| e.into())
}
/// Commit all operations to given batch.
pub fn commit_to_batch(&mut self, batch: &mut DBTransaction) -> Result<u32, UtilError> {
pub fn commit_to_batch(&mut self, batch: &mut DBTransaction) -> Result<u32> {
let mut ret = 0u32;
let mut deletes = 0usize;
for i in self.overlay.drain() {

View File

@ -16,7 +16,7 @@
//! Snappy compression bindings.
use std::fmt;
use std::{self, fmt};
use libc::{c_char, c_int, size_t};
const SNAPPY_OK: c_int = 0;
@ -56,6 +56,12 @@ extern {
#[derive(Debug)]
pub struct InvalidInput;
impl std::error::Error for InvalidInput {
fn description(&self) -> &str {
"Attempted snappy decompression with invalid input"
}
}
impl fmt::Display for InvalidInput {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Attempted snappy decompression with invalid input")

View File

@ -0,0 +1,6 @@
[package]
name = "unexpected"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]

View File

@ -0,0 +1,58 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Error utils
use std::fmt;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
/// Error indicating an expected value was not found.
pub struct Mismatch<T> {
/// Value expected.
pub expected: T,
/// Value found.
pub found: T,
}
impl<T: fmt::Display> fmt::Display for Mismatch<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!("Expected {}, found {}", self.expected, self.found))
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
/// Error indicating value found is outside of a valid range.
pub struct OutOfBounds<T> {
/// Minimum allowed value.
pub min: Option<T>,
/// Maximum allowed value.
pub max: Option<T>,
/// Value found.
pub found: T,
}
impl<T: fmt::Display> fmt::Display for OutOfBounds<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match (self.min.as_ref(), self.max.as_ref()) {
(Some(min), Some(max)) => format!("Min={}, Max={}", min, max),
(Some(min), _) => format!("Min={}", min),
(_, Some(max)) => format!("Max={}", max),
(None, None) => "".into(),
};
f.write_fmt(format_args!("Value {} out of bounds. {}", self.found, msg))
}
}