Custom Error Messages on ENFILE and EMFILE IO Errors (#8744)
* Custom Error Messages on ENFILE and EMFILE IO Errors Add custom mapping of ENFILE and EMFILE IO Errors (Failure because of missing system resource) right when chaining ioError into ::util::Network::Error to improve Error Messages given to user Note: Adds libc as a dependency to util/network * Use assert-matches for more readable tests * Fix Wording and consistency
This commit is contained in:
parent
27f3f42ce2
commit
0ebcc200c3
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -703,12 +703,14 @@ dependencies = [
|
|||||||
name = "ethcore-network"
|
name = "ethcore-network"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"assert_matches 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-crypto 0.1.0",
|
"ethcore-crypto 0.1.0",
|
||||||
"ethcore-io 1.12.0",
|
"ethcore-io 1.12.0",
|
||||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethkey 0.3.0",
|
"ethkey 0.3.0",
|
||||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.1",
|
"rlp 0.2.1",
|
||||||
"snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
|
"snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
|
||||||
]
|
]
|
||||||
|
@ -14,4 +14,9 @@ ethereum-types = "0.3"
|
|||||||
ethkey = { path = "../../ethkey" }
|
ethkey = { path = "../../ethkey" }
|
||||||
ipnetwork = "0.12.6"
|
ipnetwork = "0.12.6"
|
||||||
rlp = { path = "../rlp" }
|
rlp = { path = "../rlp" }
|
||||||
|
libc = "0.2"
|
||||||
snappy = { git = "https://github.com/paritytech/rust-snappy" }
|
snappy = { git = "https://github.com/paritytech/rust-snappy" }
|
||||||
|
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assert_matches = "1.2"
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::{io, net, fmt};
|
use std::{io, net, fmt};
|
||||||
|
use libc::{ENFILE, EMFILE};
|
||||||
use io::IoError;
|
use io::IoError;
|
||||||
use {rlp, ethkey, crypto, snappy};
|
use {rlp, ethkey, crypto, snappy};
|
||||||
|
|
||||||
@ -83,7 +84,6 @@ impl fmt::Display for DisconnectReason {
|
|||||||
error_chain! {
|
error_chain! {
|
||||||
foreign_links {
|
foreign_links {
|
||||||
SocketIo(IoError) #[doc = "Socket IO error."];
|
SocketIo(IoError) #[doc = "Socket IO error."];
|
||||||
Io(io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."];
|
|
||||||
Decompression(snappy::InvalidInput) #[doc = "Decompression error."];
|
Decompression(snappy::InvalidInput) #[doc = "Decompression error."];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +141,34 @@ error_chain! {
|
|||||||
description("Packet is too large"),
|
description("Packet is too large"),
|
||||||
display("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 {
|
||||||
|
fn from(err: io::Error) -> Self {
|
||||||
|
match err.raw_os_error() {
|
||||||
|
Some(ENFILE) => ErrorKind::ProcessTooManyFiles.into(),
|
||||||
|
Some(EMFILE) => ErrorKind::SystemTooManyFiles.into(),
|
||||||
|
_ => Error::from_kind(ErrorKind::Io(err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,3 +219,26 @@ fn test_errors() {
|
|||||||
_ => panic!("Unexpected error"),
|
_ => panic!("Unexpected error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_io_errors() {
|
||||||
|
use libc::{EMFILE, ENFILE};
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
<Error as From<io::Error>>::from(
|
||||||
|
io::Error::from_raw_os_error(ENFILE)
|
||||||
|
).kind(),
|
||||||
|
ErrorKind::ProcessTooManyFiles);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
<Error as From<io::Error>>::from(
|
||||||
|
io::Error::from_raw_os_error(EMFILE)
|
||||||
|
).kind(),
|
||||||
|
ErrorKind::SystemTooManyFiles);
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
<Error as From<io::Error>>::from(
|
||||||
|
io::Error::from_raw_os_error(0)
|
||||||
|
).kind(),
|
||||||
|
ErrorKind::Io(_));
|
||||||
|
}
|
||||||
|
@ -23,6 +23,10 @@ extern crate ethkey;
|
|||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate ipnetwork;
|
extern crate ipnetwork;
|
||||||
extern crate snappy;
|
extern crate snappy;
|
||||||
|
extern crate libc;
|
||||||
|
|
||||||
|
#[cfg(test)] #[macro_use]
|
||||||
|
extern crate assert_matches;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
Loading…
Reference in New Issue
Block a user