diff --git a/Cargo.lock b/Cargo.lock
index feb7eb08a17..19a3b45e3a4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -699,12 +699,14 @@ dependencies = [
name = "ethcore-network"
version = "1.11.0"
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)",
"ethcore-crypto 0.1.0",
"ethcore-io 1.11.0",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.3.0",
"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",
"snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
]
diff --git a/util/network/Cargo.toml b/util/network/Cargo.toml
index f98cd9e93ca..62d174f36b8 100644
--- a/util/network/Cargo.toml
+++ b/util/network/Cargo.toml
@@ -14,4 +14,9 @@ ethereum-types = "0.3"
ethkey = { path = "../../ethkey" }
ipnetwork = "0.12.6"
rlp = { path = "../rlp" }
+libc = "0.2"
snappy = { git = "https://github.com/paritytech/rust-snappy" }
+
+
+[dev-dependencies]
+assert_matches = "1.2"
diff --git a/util/network/src/error.rs b/util/network/src/error.rs
index aab645b2ded..6caceefea20 100644
--- a/util/network/src/error.rs
+++ b/util/network/src/error.rs
@@ -15,6 +15,7 @@
// along with Parity. If not, see .
use std::{io, net, fmt};
+use libc::{ENFILE, EMFILE};
use io::IoError;
use {rlp, ethkey, crypto, snappy};
@@ -83,7 +84,6 @@ impl fmt::Display for DisconnectReason {
error_chain! {
foreign_links {
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."];
}
@@ -141,6 +141,34 @@ error_chain! {
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 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))
+ }
}
}
@@ -185,3 +213,26 @@ fn test_errors() {
_ => panic!("Unexpeceted error"),
}
}
+
+#[test]
+fn test_io_errors() {
+ use libc::{EMFILE, ENFILE};
+
+ assert_matches!(
+ >::from(
+ io::Error::from_raw_os_error(ENFILE)
+ ).kind(),
+ ErrorKind::ProcessTooManyFiles);
+
+ assert_matches!(
+ >::from(
+ io::Error::from_raw_os_error(EMFILE)
+ ).kind(),
+ ErrorKind::SystemTooManyFiles);
+
+ assert_matches!(
+ >::from(
+ io::Error::from_raw_os_error(0)
+ ).kind(),
+ ErrorKind::Io(_));
+}
diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs
index 673e4dab357..39402e04a96 100644
--- a/util/network/src/lib.rs
+++ b/util/network/src/lib.rs
@@ -23,6 +23,10 @@ extern crate ethkey;
extern crate rlp;
extern crate ipnetwork;
extern crate snappy;
+extern crate libc;
+
+#[cfg(test)] #[macro_use]
+extern crate assert_matches;
#[macro_use]
extern crate error_chain;