Merge pull request #1116 from rphmeier/die_display

Have `die_with_error` use `fmt::Display` rather than Debug
This commit is contained in:
Marek Kotewicz 2016-05-24 20:00:50 +02:00
commit bf46531372
7 changed files with 234 additions and 3 deletions

View File

@ -60,6 +60,28 @@ pub enum TransactionError {
InvalidGasLimit(OutOfBounds<U256>), InvalidGasLimit(OutOfBounds<U256>),
} }
impl fmt::Display for TransactionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::TransactionError::*;
let msg = match *self {
AlreadyImported => "Already imported".into(),
Old => "No longer valid".into(),
TooCheapToReplace => "Gas price too low to replace".into(),
LimitReached => "Transaction limit reached".into(),
InsufficientGasPrice { minimal, got } =>
format!("Insufficient gas price. Min={}, Given={}", minimal, got),
InsufficientBalance { balance, cost } =>
format!("Insufficient balance for transaction. Balance={}, Cost={}",
balance, cost),
GasLimitExceeded { limit, got } =>
format!("Gas limit exceeded. Limit={}, Given={}", limit, got),
InvalidGasLimit(ref err) => format!("Invalid gas limit. {}", err),
};
f.write_fmt(format_args!("Transaction error ({})", msg))
}
}
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
/// Errors concerning block processing. /// Errors concerning block processing.
pub enum BlockError { pub enum BlockError {
@ -98,7 +120,7 @@ pub enum BlockError {
MismatchedH256SealElement(Mismatch<H256>), MismatchedH256SealElement(Mismatch<H256>),
/// Proof-of-work aspect of seal, which we assume is a 256-bit value, is invalid. /// Proof-of-work aspect of seal, which we assume is a 256-bit value, is invalid.
InvalidProofOfWork(OutOfBounds<U256>), InvalidProofOfWork(OutOfBounds<U256>),
/// Some low-level aspect of the seal in incorrect. /// Some low-level aspect of the seal is incorrect.
InvalidSeal, InvalidSeal,
/// Gas limit header field is invalid. /// Gas limit header field is invalid.
InvalidGasLimit(OutOfBounds<U256>), InvalidGasLimit(OutOfBounds<U256>),
@ -121,6 +143,43 @@ pub enum BlockError {
UnknownUncleParent(H256), UnknownUncleParent(H256),
} }
impl fmt::Display for BlockError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::BlockError::*;
let msg = match *self {
TooManyUncles(ref oob) => format!("Block has too many uncles. {}", oob),
ExtraDataOutOfBounds(ref oob) => format!("Extra block data too long. {}", oob),
InvalidSealArity(ref mis) => format!("Block seal in incorrect format: {}", mis),
TooMuchGasUsed(ref oob) => format!("Block has too much gas used. {}", oob),
InvalidUnclesHash(ref mis) => format!("Block has invalid uncles hash: {}", mis),
UncleTooOld(ref oob) => format!("Uncle block is too old. {}", oob),
UncleIsBrother(ref oob) => format!("Uncle from same generation as block. {}", oob),
UncleInChain(ref hash) => format!("Uncle {} already in chain", hash),
UncleParentNotInChain(ref hash) => format!("Uncle {} has a parent not in the chain", hash),
InvalidStateRoot(ref mis) => format!("Invalid state root in header: {}", mis),
InvalidGasUsed(ref mis) => format!("Invalid gas used in header: {}", mis),
InvalidTransactionsRoot(ref mis) => format!("Invalid transactions root in header: {}", mis),
DifficultyOutOfBounds(ref oob) => format!("Invalid block difficulty: {}", oob),
InvalidDifficulty(ref mis) => format!("Invalid block difficulty: {}", mis),
MismatchedH256SealElement(ref mis) => format!("Seal element out of bounds: {}", mis),
InvalidProofOfWork(ref oob) => format!("Block has invalid PoW: {}", oob),
InvalidSeal => "Block has invalid seal.".into(),
InvalidGasLimit(ref oob) => format!("Invalid gas limit: {}", oob),
InvalidReceiptsRoot(ref mis) => format!("Invalid receipts trie root in header: {}", mis),
InvalidTimestamp(ref oob) => format!("Invalid timestamp in header: {}", oob),
InvalidLogBloom(ref oob) => format!("Invalid log bloom in header: {}", oob),
InvalidParentHash(ref mis) => format!("Invalid parent hash: {}", mis),
InvalidNumber(ref mis) => format!("Invalid number in header: {}", mis),
RidiculousNumber(ref oob) => format!("Implausible block number. {}", oob),
UnknownParent(ref hash) => format!("Unknown parent: {}", hash),
UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash),
};
f.write_fmt(format_args!("Block error ({})", msg))
}
}
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
/// Import to the block queue result /// Import to the block queue result
pub enum ImportError { pub enum ImportError {
@ -132,6 +191,18 @@ pub enum ImportError {
KnownBad, KnownBad,
} }
impl fmt::Display for ImportError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match *self {
ImportError::AlreadyInChain => "block already in chain",
ImportError::AlreadyQueued => "block already in the block queue",
ImportError::KnownBad => "block known to be bad",
};
f.write_fmt(format_args!("Block import error ({})", msg))
}
}
#[derive(Debug)] #[derive(Debug)]
/// General error type which should be capable of representing all errors in ethcore. /// General error type which should be capable of representing all errors in ethcore.
pub enum Error { pub enum Error {
@ -155,6 +226,23 @@ pub enum Error {
PowInvalid, PowInvalid,
} }
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Client(ref err) => f.write_fmt(format_args!("{}", err)),
Error::Util(ref err) => f.write_fmt(format_args!("{}", err)),
Error::Block(ref err) => f.write_fmt(format_args!("{}", err)),
Error::Execution(ref err) => f.write_fmt(format_args!("{}", err)),
Error::Transaction(ref err) => f.write_fmt(format_args!("{}", err)),
Error::Import(ref err) => f.write_fmt(format_args!("{}", err)),
Error::UnknownEngineName(ref name) =>
f.write_fmt(format_args!("Unknown engine name ({})", name)),
Error::PowHashInvalid => f.write_str("Invalid or out of date PoW hash."),
Error::PowInvalid => f.write_str("Invalid nonce or mishash"),
}
}
}
/// Result of import block operation. /// Result of import block operation.
pub type ImportResult = Result<H256, Error>; pub type ImportResult = Result<H256, Error>;

View File

@ -21,6 +21,7 @@ use util::Bytes;
use trace::Trace; use trace::Trace;
use types::log_entry::LogEntry; use types::log_entry::LogEntry;
use ipc::binary::BinaryConvertError; use ipc::binary::BinaryConvertError;
use std::fmt;
use std::mem; use std::mem;
use std::collections::VecDeque; use std::collections::VecDeque;
@ -104,6 +105,28 @@ pub enum ExecutionError {
TransactionMalformed(String), TransactionMalformed(String),
} }
impl fmt::Display for ExecutionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::ExecutionError::*;
let msg = match *self {
NotEnoughBaseGas { required, got } =>
format!("Not enough base gas. {} is required, but only {} paid", required, got),
BlockGasLimitReached { gas_limit, gas_used, gas } =>
format!("Block gas limit reached. The limit is {}, {} has \
already been used, and {} more is required", gas_limit, gas_used, gas),
InvalidNonce { expected, got } =>
format!("Invalid transaction nonce: expected {}, found {}", expected, got),
NotEnoughCash { required, got } =>
format!("Cost of transaction exceeds sender balance. {} is required \
but the sender only has {}", required, got),
Internal => "Internal evm error".into(),
TransactionMalformed(ref err) => format!("Malformed transaction: {}", err),
};
f.write_fmt(format_args!("Transaction execution error ({}).", msg))
}
}
/// Transaction execution result. /// Transaction execution result.
pub type ExecutionResult = Result<Executed, ExecutionError>; pub type ExecutionResult = Result<Executed, ExecutionError>;

View File

@ -31,11 +31,16 @@ pub fn die_with_error(module: &'static str, e: ethcore::error::Error) -> ! {
match e { match e {
Error::Util(UtilError::StdIo(e)) => die_with_io_error(module, e), Error::Util(UtilError::StdIo(e)) => die_with_io_error(module, e),
Error::Client(ClientError::Trace(e)) => die_with_message(&format!("{}", e)), Error::Client(ClientError::Trace(e)) => die_with_message(&format!("{}", e)),
_ => die!("{}: {:?}", module, e), _ => {
trace!(target: module, "{:?}", e);
die!("{}: {}", module, e);
}
} }
} }
pub fn die_with_io_error(module: &'static str, e: std::io::Error) -> ! { pub fn die_with_io_error(module: &'static str, e: std::io::Error) -> ! {
trace!(target: module, "{:?}", e);
match e.kind() { match e.kind() {
std::io::ErrorKind::PermissionDenied => { std::io::ErrorKind::PermissionDenied => {
die!("{}: No permissions to bind to specified port.", module) die!("{}: No permissions to bind to specified port.", module)
@ -46,7 +51,7 @@ pub fn die_with_io_error(module: &'static str, e: std::io::Error) -> ! {
std::io::ErrorKind::AddrNotAvailable => { std::io::ErrorKind::AddrNotAvailable => {
die!("{}: Could not use specified interface or given address is invalid.", module) die!("{}: Could not use specified interface or given address is invalid.", module)
}, },
_ => die!("{}: {:?}", module, e), _ => die!("{}: {}", module, e),
} }
} }

View File

@ -21,6 +21,7 @@ use bytes::*;
use secp256k1::{key, Secp256k1}; use secp256k1::{key, Secp256k1};
use rand::os::OsRng; use rand::os::OsRng;
use sha3::Hashable; use sha3::Hashable;
use std::fmt;
/// Secret key for secp256k1 EC operations. 256 bit generic "hash" data. /// Secret key for secp256k1 EC operations. 256 bit generic "hash" data.
pub type Secret = H256; pub type Secret = H256;
@ -69,6 +70,20 @@ pub enum CryptoError {
Io(::std::io::Error), Io(::std::io::Error),
} }
impl fmt::Display for CryptoError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match *self {
CryptoError::InvalidSecret => "Invalid secret key".into(),
CryptoError::InvalidPublic => "Invalid public key".into(),
CryptoError::InvalidSignature => "Invalid EC signature".into(),
CryptoError::InvalidMessage => "Invalid AES message".into(),
CryptoError::Io(ref err) => format!("I/O error: {}", err),
};
f.write_fmt(format_args!("Crypto error ({})", msg))
}
}
impl From<::secp256k1::Error> for CryptoError { impl From<::secp256k1::Error> for CryptoError {
fn from(e: ::secp256k1::Error) -> CryptoError { fn from(e: ::secp256k1::Error) -> CryptoError {
match e { match e {

View File

@ -30,6 +30,16 @@ pub enum BaseDataError {
NegativelyReferencedHash(H256), NegativelyReferencedHash(H256),
} }
impl fmt::Display for BaseDataError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
BaseDataError::NegativelyReferencedHash(hash) =>
f.write_fmt(format_args!("Entry {} removed from database more times \
than it was added.", hash)),
}
}
}
#[derive(Debug)] #[derive(Debug)]
/// General error type which should be capable of representing all errors in ethcore. /// General error type which should be capable of representing all errors in ethcore.
pub enum UtilError { pub enum UtilError {
@ -57,6 +67,24 @@ pub enum UtilError {
BadSize, BadSize,
} }
impl fmt::Display for UtilError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
UtilError::Crypto(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::StdIo(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::Io(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::AddressParse(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::AddressResolve(Some(ref err)) => f.write_fmt(format_args!("{}", err)),
UtilError::AddressResolve(_) => f.write_str("Failed to resolve network address."),
UtilError::FromHex(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::BaseData(ref err) => f.write_fmt(format_args!("{}", err)),
UtilError::Network(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."),
}
}
}
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
/// Error indicating an expected value was not found. /// Error indicating an expected value was not found.
@ -67,6 +95,12 @@ pub struct Mismatch<T: fmt::Debug> {
pub found: T, pub found: T,
} }
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))
}
}
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
/// Error indicating value found is outside of a valid range. /// Error indicating value found is outside of a valid range.
pub struct OutOfBounds<T: fmt::Debug> { pub struct OutOfBounds<T: fmt::Debug> {
@ -78,6 +112,19 @@ pub struct OutOfBounds<T: fmt::Debug> {
pub found: T, 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 { impl From<FromHexError> for UtilError {
fn from(err: FromHexError) -> UtilError { fn from(err: FromHexError) -> UtilError {
UtilError::FromHex(err) UtilError::FromHex(err)

View File

@ -56,6 +56,7 @@ mod service;
mod worker; mod worker;
use mio::{EventLoop, Token}; use mio::{EventLoop, Token};
use std::fmt;
#[derive(Debug)] #[derive(Debug)]
/// IO Error /// IO Error
@ -64,6 +65,16 @@ pub enum IoError {
Mio(::std::io::Error), Mio(::std::io::Error),
} }
impl fmt::Display for IoError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// just defer to the std implementation for now.
// we can refine the formatting when more variants are added.
match *self {
IoError::Mio(ref std_err) => std_err.fmt(f)
}
}
}
impl<Message> From<::mio::NotifyError<service::IoMessage<Message>>> for IoError where Message: Send + Clone { impl<Message> From<::mio::NotifyError<service::IoMessage<Message>>> for IoError where Message: Send + Clone {
fn from(_err: ::mio::NotifyError<service::IoMessage<Message>>) -> IoError { fn from(_err: ::mio::NotifyError<service::IoMessage<Message>>) -> IoError {
IoError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error")) IoError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error"))

View File

@ -17,6 +17,7 @@
use io::IoError; use io::IoError;
use crypto::CryptoError; use crypto::CryptoError;
use rlp::*; use rlp::*;
use std::fmt;
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DisconnectReason pub enum DisconnectReason
@ -56,6 +57,30 @@ impl DisconnectReason {
} }
} }
impl fmt::Display for DisconnectReason {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::DisconnectReason::*;
let msg = match *self {
DisconnectRequested => "disconnect requested",
TCPError => "TCP error",
BadProtocol => "bad protocol",
UselessPeer => "useless peer",
TooManyPeers => "too many peers",
DuplicatePeer => "duplicate peer",
IncompatibleProtocol => "incompatible protocol",
NullIdentity => "null identity",
ClientQuit => "client quit",
UnexpectedIdentity => "unexpected identity",
LocalIdentity => "local identity",
PingTimeout => "ping timeout",
Unknown => "unknown",
};
f.write_str(msg)
}
}
#[derive(Debug)] #[derive(Debug)]
/// Network error. /// Network error.
pub enum NetworkError { pub enum NetworkError {
@ -73,6 +98,23 @@ pub enum NetworkError {
Io(IoError), Io(IoError),
} }
impl fmt::Display for NetworkError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::NetworkError::*;
let msg = match *self {
Auth => "Authentication failure".into(),
BadProtocol => "Bad protocol".into(),
Expired => "Expired message".into(),
PeerNotFound => "Peer not found".into(),
Disconnect(ref reason) => format!("Peer disconnected: {}", reason),
Io(ref err) => format!("Socket I/O error: {}", err),
};
f.write_fmt(format_args!("Network error ({})", msg))
}
}
impl From<DecoderError> for NetworkError { impl From<DecoderError> for NetworkError {
fn from(_err: DecoderError) -> NetworkError { fn from(_err: DecoderError) -> NetworkError {
NetworkError::Auth NetworkError::Auth