-
Notifications
You must be signed in to change notification settings - Fork 20
#71 Should now bubble errors up the scope in health.rs #81
Conversation
Wow... ok, I'm going to fix this... sorry about that! |
Going to close this until I can get it figured out^^; The Error types are getting me at the moment, but I'll get it figured out^^; |
src/health.rs
Outdated
@@ -25,7 +25,7 @@ impl HealthCheck { | |||
} | |||
|
|||
pub fn run(&self) { | |||
let mut core = Core::new().unwrap(); | |||
let mut core = trey!Core::new()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you mean try!
😉
don't be impatient with yourself. |
src/health.rs
Outdated
@@ -25,7 +25,7 @@ impl HealthCheck { | |||
} | |||
|
|||
pub fn run(&self) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to use try!
, the run
method needs to return an error. In this case, it looks like Core::new
uses io::Result
. So the run
method could return something like io::Result<()>
.
@mclark4386 this looks really close. i am hjr3 on irc (irc.mozilla.org) if you want to talk through anything. |
Thanks for your time! Yeah, I figured out that it needed to return a Result and then have been running into issues with the return type because it looks like there are different error types that it may return and they aren't compatible. Here are the errors I'm getting with the latest code:
I could be reading that wrong, but it almost seems like the error type from the first error (tokio_timer::TimerError) doesn't have the functionality to convert to a compatible error for the io::Result and then the second error... I'm not sure. Maybe the same thing? Thank you for being patient with me! I'm doing this on the side and have had a sudden surge at work so it's be hectic^^; |
Is there a way to trigger github to update the the view of the code here? Would reopening the issue do that? |
@mclark4386 i opened the issue back up. i see travis running. |
One idea: |
src/health.rs
Outdated
@@ -66,6 +67,7 @@ impl HealthCheck { | |||
Ok(()) | |||
}).map_err(|_| {}); | |||
|
|||
core.run(work).unwrap(); | |||
try!(core.run(work)); | |||
Ok(()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The try!
followed by Ok
is redundant. What the try!
macro expands to is something like:
match core.run(work) {
Err(e) => return e,
Ok(o) => o
}
so you can get rid of the Ok(())
and have core.run(work)
. Notice there is no semi-colon. However, that will not fix the compiler error shown in travis-ci.
I originally told you the wrong return type for Core::run
. With the version of tokio-core that weldr is running on, core.run(work)
returns Result<F::Item, F::Error>
which is the Item and Error type of the future. Because the work future sent to core.run
maps all errors to ()
, we cannot use try!
here One thing you could do is:
core.run(work).map_err(|_| io::Error::new(io::ErrorKind::Other, "Core failed"))
The better thing to do would be to change map_err at the end of the work
future .map_err(From::from)
. This says to take any error returned by the timer.interval
stream and call std::convert::From::from on the result. You can also write this using a more explicit closure .map_err(|e| From::from(e))
. This works because the work
future returns a tokio_timer::TimerError
type if there is an error. The tokio-timer crate implemented the std::convert::From
trait for tokio_timer::TimerError
to be converted to io::Error
. (btw, I didn't go and read the source code for tokio-timer to figure that out. I mapped the error to From::from
and crossed my fingers that it was already implemented. it is a common pattern).
One more error to go! When you have try!(server.url().join(&self.uri_path));
the compiler is complaining that server.url().join(&self.uri_path)
returns a hyper::error::ParseError
type on error but timer.interval(self.interval).for_each()
is expecting a tokio_timer::TimerError
. Unlike our previous example, the hyper crate does not know how to convert hyper::error::ParseError into
tokio_timer::TimerError. If you look at the [TimerError](https://github.com/tokio-rs/tokio-timer/blob/f044bd2f58d1192aff774eac9ee06852fd90a5a7/src/timer.rs#L41) in source code it makes sense. There is no logical conversion of a url parsing error into a timeout error. Instead of using
try!` and bubbling up the error, we may want to just handle it here. You might think about doing something like:
let url = match server.url().join(&self.uri_path) {
Ok(url) => url,
Err(e) => {
error!("Invalid health check url: {:?}", e);
return Ok(());
}
};
The main difference here is that we are returning the Ok
variant instead of the Err
variant. If we think about this, it makes sense. timer.interval(...).for_each
is of type Stream
from the futures crate. If we return an Err
, then the entire stream is halted immediately. We probably do not want to halt the entire stream here, but instead abort this particular server. I say probably because this is one of those errors that only happens if either a) the server url is not valid or b) the uri path is not valid. In either case, it is user supplied data that has to be fixed.
I did not expect my comment to get so long. I appreciate your work here. If nothing else, it has forced me to think through how these interactions need to work. You are very close to getting it working! I also agree with @yanns that maybe a custom error type might be good here. However, if you want to get this working as-is for now, we can always put in the custom error type later.
@hjr3 had a big long post and then accidentally left the page and lost it all when I came back. Main gist is that I was still having the first error when I did the custom error (HealthCheckError), but I guess I could have made your solution work for it, but thought your solution seemed more idiomatic... but I don't know. Either way I implemented your changes and I'm not positive how to fix that error (can see it in the stable log in travis). Thank you for your time and patience! I'm learning a ton thanks to this^^; |
@mclark4386 this is the long post: #81 (comment) |
@mclark4386 thank you for working on this. It was unexpectedly more complicated than I originally thought it would be! |
Please let me know if you would rather this be handled differently or if you would like anything tweaked! This is one of my first rust patches, so VERY open to any needed changes! Thanks!