Skip to content

Commit

Permalink
Custom Error Messages on ENFILE and EMFILE IO Errors (openethereum#8744)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
gnunicorn authored and VladLupashevskyi committed Jun 1, 2018
1 parent e300472 commit f852531
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions util/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
53 changes: 52 additions & 1 deletion util/network/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use std::{io, net, fmt};
use libc::{ENFILE, EMFILE};
use io::IoError;
use {rlp, ethkey, crypto, snappy};

Expand Down Expand Up @@ -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."];
}

Expand Down Expand Up @@ -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<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))
}
}
}

Expand Down Expand Up @@ -191,3 +219,26 @@ fn test_errors() {
_ => 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(_));
}
4 changes: 4 additions & 0 deletions util/network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit f852531

Please sign in to comment.