I'm just starting to learn rust and as a learning project - after reading half of the "Programming Rust" Oreilly book - I'm trying to build some kind of pow / puma-dev but not specific to rails (that means serve local directories and reverse proxy local ports).
The web part of it is to check the Host header on the request, query local state for type of response required (e.g. serve specific directory) and respond accordingly. I tried several ways to achieve this but I always get to incompatible types on match arms. The furthest I got (at least in terms of types that I can understand) is by following and expanding on this example of hyper-staticfile. I more or less copied this implementation and added another item to the MainFuture enum like that:
Both futures are the result of library calls (hyper-staticfile and hyper-reverse-proxy).
So the Future implementation looks like this:
impl Future for MainFuture {
type Item = Response<Body>;
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match *self {
MainFuture::Static(ref mut future) => future.poll(),
MainFuture::ReverseProxy(ref mut future) => future.poll(),
}
}
}
The problem is that the Static future returns std::io::Error as error type and the reverse proxy returns hyper::Error. Compiling it gets me:
error[E0308]: match arms have incompatible types
--> src/web/mod.rs:33:51
|
31 | / match *self {
32 | | MainFuture::Static(ref mut future) => future.poll(),
| | ------------- this is found to be of type `std::result::Result<futures::poll::Async<http::response::Response<hyper::body::body::Body>>, std::io::Error>`
33 | | MainFuture::ReverseProxy(ref mut future) => future.poll(),
| | ^^^^^^^^^^^^^ expected struct `std::io::Error`, found struct `hyper::error::Error`
34 | | }
| |_____- `match` arms have incompatible types
|
= note: expected type `std::result::Result<_, std::io::Error>`
found type `std::result::Result<_, hyper::error::Error>`
error: aborting due to previous error
As far as I understand error chaining won't help here as I'm not using ?. Can anyone please help me solve this?
You need to convert both error into a custom error type you'll have to define.
I can't stress enough the reading of this blog post that covers Error handling in Rust:
Thanks Geobomatic for the interesting links. I didn't know the first one but I do use failure.
I read through the examples of the first article but maybe I miss something. Any kind of error chaining / automatic conversion with From trait only works when using the ? macro or if I return them directly from a function. I don't understand how do I use it in my example unless I can somehow manipulate the Poll result of the provided future.poll() functions.
To make my question even clearer, let's assume MyError is a real error implementing Error, Display and Debug.
The different errors from the future.poll() are returned directly from 3rd party futures. I'm not sure how to manipulate them to return my type of error.