title: Creating a hyper service with custom error type
body: <p>I am trying to create a REST server using hyper. For robust error handling, I would prefer to have the service return a future with a custom error type that wraps hyper, Diesel, and other errors. Unfortunately, <code>hyper::Response</code> seems to hard-code a stream with error type <code>hyper::error::Error</code>, which conflicts with the error type I've defined for my service. I see a couple possible solutions:</p>
  
  <ol>
  <li><p>Make my service return my custom error type by modifying <code>hyper::Response</code>, which seems hard.</p></li>
  <li><p>Wrap non-hyper errors in a <code>hyper::error::Error</code>. This seems hacky.</p></li>
  <li><p>Something else. It seems like I'm missing the "right" way to do this.</p></li>
  </ol>
  
  <p>The following code shows what I think I want to do:</p>
  
  <pre><code>extern crate diesel;
  extern crate futures;
  extern crate hyper;
  
  use futures::future::{ok, Future};
  use hyper::StatusCode;
  use hyper::server::{Request, Response, Service};
  
  fn main() {
      let address = "127.0.0.1:8080".parse().unwrap();
      let server = hyper::server::Http::new()
          .bind(&amp;address, move || Ok(ApiService {}))
          .unwrap();
      server.run().unwrap();
  }
  
  pub struct ApiService;
  
  impl Service for ApiService {
      type Request = Request;
      type Response = Response;
      type Error = Error;
      type Future = Box&lt;Future&lt;Item = Self::Response, Error = Self::Error&gt;&gt;;
  
      fn call(&amp;self, request: Request) -&gt; Self::Future {
          Box::new(ok(Response::new().with_status(StatusCode::Ok)))
      }
  }
  
  #[derive(Debug)]
  pub enum Error {
      Request(hyper::Error),
      DatabaseResult(diesel::result::Error),
      DatabaseConnection(diesel::ConnectionError),
      Other(String),
  }
  
  // omitted impl of Display, std::error::Error for brevity
  </code></pre>
  
  <p>This code results in a compiler error which I believe is because the <code>bind</code> function requires that the response type have a body that is a stream with error type <code>hyper::error::Error</code>:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0271]: type mismatch resolving `&lt;ApiService as hyper::client::Service&gt;::Error == hyper::Error`
    --&gt; src/main.rs:14:10
     |
  14 |         .bind(&amp;address, move || Ok(ApiService {}))
     |          ^^^^ expected enum `Error`, found enum `hyper::Error`
     |
     = note: expected type `Error`
                found type `hyper::Error`
  </code></pre>