It’s been cited in the “catching functions” thread too, and in a few Rust2018 blog posts, from what I saw.
It’s ugly for two reasons: one is the one you say: is it ok or not?
The other is that it hides the “non happy path”. While reading the code it appears to be the correct result, but in effect it hides the possibility of an error.
And, to take my original problem, look at this:
pub fn render_page(&self, tpl_type: &str, data: &Object) -> Result<String> {
Ok(self.engine.read().unwrap()
.render(tpl_type, data)
.context(ErrorKind::Error(format!("Unable to render template {}", tpl_type)))?)
}
It’s, at least, a code smell. Removing the whole Ok( and ?) makes it much more readable, and quickly glancing at the signature makes it clear that it can return an error, while the Ok makes it look like it won’t.
You can mitigate it by assigning to a temp var:
pub fn render_page(&self, tpl_type: &str, data: &Object) -> Result<String> {
let res = self.engine.read().unwrap()
.render(tpl_type, data)
.context(ErrorKind::Error(format!("Unable to render template {}", tpl_type)))?;
Ok(res)
}
But don’t you think this is simpler and more readable?
pub fn render_page(&self, tpl_type: &str, data: &Object) -> Result<String> {
self.engine.read().unwrap()
.render(tpl_type, data)
.context(ErrorKind::Error(format!("Unable to render template {}", tpl_type)))
}