diff --git a/Cargo.toml b/Cargo.toml
index e6624a0..cce806f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2018"
 [dependencies]
 bytes = "0.4.12"
 clap = "2.33.0"
-custom_error = "1.3.0"
+custom_error = "1.6.0"
 futures = "0.1.28"
 http = "0.1.17"
 hyper = "0.12.31"
diff --git a/src/commands/filter.rs b/src/commands/filter.rs
index 41fc9ee..55c9ee4 100644
--- a/src/commands/filter.rs
+++ b/src/commands/filter.rs
@@ -39,6 +39,6 @@ pub fn run(args: &ArgMatches) -> Result<(), WebmetroError> {
     }
 
     Runtime::new().unwrap().block_on(chunk_stream.for_each(|chunk| {
-        io::stdout().write_all(chunk.as_ref()).map_err(WebmetroError::IoError)
+        io::stdout().write_all(chunk.as_ref()).map_err(WebmetroError::from)
     }))
 }
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index e6decf5..3acf871 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -23,5 +23,5 @@ pub mod send;
 pub fn stdin_stream() -> impl Stream<Item = impl Buf, Error = WebmetroError> {
     FramedRead::new(AllowStdIo::new(stdin()), BytesCodec::new())
     .map(|bytes| bytes.into_buf())
-    .map_err(WebmetroError::IoError)
+    .map_err(WebmetroError::from)
 }
diff --git a/src/commands/relay.rs b/src/commands/relay.rs
index ca49d7b..bae0a6e 100644
--- a/src/commands/relay.rs
+++ b/src/commands/relay.rs
@@ -1,4 +1,3 @@
-use std::error::Error;
 use std::net::ToSocketAddrs;
 use std::sync::{
     Arc,
@@ -53,9 +52,9 @@ fn get_stream(channel: Handle) -> impl Stream<Item = Bytes, Error = WebmetroErro
     .map_err(|err| match err {})
 }
 
-fn post_stream(channel: Handle, stream: impl Stream<Item = impl Buf, Error = impl Error + Send + Sync + 'static>) -> impl Stream<Item = Bytes, Error = WebmetroError> {
+fn post_stream(channel: Handle, stream: impl Stream<Item = impl Buf, Error = warp::Error>) -> impl Stream<Item = Bytes, Error = WebmetroError> {
     let source = stream
-        .map_err(WebmetroError::from_err)
+        .map_err(WebmetroError::from)
         .parse_ebml().with_soft_limit(BUFFER_LIMIT)
         .chunk_webm().with_soft_limit(BUFFER_LIMIT);
     let sink = Transmitter::new(channel);
diff --git a/src/commands/send.rs b/src/commands/send.rs
index 148e9ad..a16adee 100644
--- a/src/commands/send.rs
+++ b/src/commands/send.rs
@@ -46,7 +46,7 @@ pub fn run(args: &ArgMatches) -> Result<(), WebmetroError> {
 
     let url_str = match args.value_of("url") {
         Some(url) => String::from(url),
-        _ => return Err(WebmetroError::from_str("Listen address wasn't provided"))
+        _ => return Err("Listen address wasn't provided".into())
     };
 
     if args.is_present("throttle") {
@@ -63,7 +63,7 @@ pub fn run(args: &ArgMatches) -> Result<(), WebmetroError> {
     
     let request = Request::put(url_str)
     .body(request_payload)
-    .map_err(WebmetroError::from_err)?;
+    .map_err(WebmetroError::from)?;
 
     let client = Client::builder().build(HttpConnector::new(1));
     let future = client.request(request)
@@ -72,7 +72,7 @@ pub fn run(args: &ArgMatches) -> Result<(), WebmetroError> {
             Ok(())
         })
     })
-    .map_err(WebmetroError::from_err);
+    .map_err(WebmetroError::from);
 
     Runtime::new().unwrap().block_on(future)
 }
diff --git a/src/error.rs b/src/error.rs
index 7a0ca38..9d29a86 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,75 +1,19 @@
-use std::{
-    error::Error,
-    fmt::{
-        Display,
-        Formatter,
-        Result as FmtResult
-    },
-    io::Error as IoError
-};
 
-use crate::ebml::EbmlError;
+use custom_error::custom_error;
 
-#[derive(Debug)]
-pub enum WebmetroError {
-    ResourcesExceeded,
-    EbmlError(EbmlError),
-    IoError(IoError),
-    Unknown(Box<Error + Send + Sync>)
+custom_error!{pub WebmetroError
+    ResourcesExceeded = "resources exceeded",
+    EbmlError{source: crate::ebml::EbmlError} = "EBML error",
+    HttpError{source: http::Error} = "HTTP error",
+    HyperError{source: hyper::Error} = "Hyper error",
+    IoError{source: std::io::Error} = "IO error",
+    TimerError{source: tokio::timer::Error} = "Timer error",
+    WarpError{source: warp::Error} = "Warp error",
+    ApplicationError{message: String} = "{message}"
 }
 
-impl WebmetroError {
-    pub fn from_str(string: &str) -> WebmetroError {
-        string.into()
-    }
-
-    pub fn from_err<E: Error + Send + Sync + 'static>(err: E) -> WebmetroError {
-        WebmetroError::Unknown(Box::new(err))
-    }
-}
-
-impl Display for WebmetroError {
-    fn fmt(&self, f: &mut Formatter) -> FmtResult {
-        match self {
-            &WebmetroError::ResourcesExceeded => write!(f, "resources exceeded"),
-            &WebmetroError::EbmlError(ref err) => err.fmt(f),
-            &WebmetroError::IoError(ref err) => err.fmt(f),
-            &WebmetroError::Unknown(ref err) => err.fmt(f),
-        }
-    }
-}
-impl Error for WebmetroError {
-    fn description(&self) -> &str {
-        match self {
-            &WebmetroError::ResourcesExceeded => "resources exceeded",
-            &WebmetroError::EbmlError(ref err) => err.description(),
-            &WebmetroError::IoError(ref err) => err.description(),
-            &WebmetroError::Unknown(ref err) => err.description(),
-        }
-    }
-}
-
-impl From<EbmlError> for WebmetroError {
-    fn from(err: EbmlError) -> WebmetroError {
-        WebmetroError::EbmlError(err)
-    }
-}
-
-impl From<IoError> for WebmetroError {
-    fn from(err: IoError) -> WebmetroError {
-        WebmetroError::IoError(err)
-    }
-}
-
-impl From<Box<Error + Send + Sync>> for WebmetroError {
-    fn from(err: Box<Error + Send + Sync>) -> WebmetroError {
-        WebmetroError::Unknown(err)
-    }
-}
-
-impl<'a> From<&'a str> for WebmetroError {
-    fn from(err: &'a str) -> WebmetroError {
-        let error: Box<Error + Send + Sync> = err.into();
-        WebmetroError::Unknown(error)
+impl From<&str> for WebmetroError {
+    fn from(message: &str) -> WebmetroError {
+        WebmetroError::ApplicationError{message: message.into()}
     }
 }
diff --git a/src/fixers.rs b/src/fixers.rs
index ed0df2c..aeac505 100644
--- a/src/fixers.rs
+++ b/src/fixers.rs
@@ -98,7 +98,7 @@ impl<S: Stream<Item = Chunk, Error = WebmetroError>> Stream for Throttle<S>
 
     fn poll(&mut self) -> Result<Async<Option<Self::Item>>, WebmetroError> {
         match self.sleep.poll() {
-            Err(err) => return Err(WebmetroError::Unknown(Box::new(err))),
+            Err(err) => return Err(err.into()),
             Ok(Async::NotReady) => return Ok(Async::NotReady),
             Ok(Async::Ready(())) => { /* can continue */ }
         }
diff --git a/src/stream_parser.rs b/src/stream_parser.rs
index 388f89c..d9e4d0a 100644
--- a/src/stream_parser.rs
+++ b/src/stream_parser.rs
@@ -55,9 +55,9 @@ impl<I: Buf, S: Stream<Item = I, Error = WebmetroError>> EbmlStreamingParser<S>
                 Ok(None) => {
                     // need to refill buffer, below
                 },
-                other => return other.map_err(WebmetroError::EbmlError).and_then(move |_| {
+                other => return other.map_err(WebmetroError::from).and_then(move |_| {
                     match T::decode_element(&self.buffer) {
-                        Err(err) => Err(WebmetroError::EbmlError(err)),
+                        Err(err) => Err(err.into()),
                         Ok(None) => panic!("Buffer was supposed to have enough data to parse element, somehow did not."),
                         Ok(Some((element, element_size))) => {
                             self.last_read = element_size;