Closed becky112358 closed 2 years ago
Doesn't the existing implementation catch it? Or do you want something more fine-grained?
I don't think the existing implementation catches it, but I'm still learning and can believe I'm wrong!
I created this repository to demonstrate my feature request: https://github.com/becky112358/rust_result_experimentation
Essentially the repository code is as follows:
use std::io::Result;
use std::process::Command;
fn main() -> Result<()> {
Command::new("ping").arg("192.168.1.1").output()?;
chrono::Duration::seconds(-5).to_std();
hm305p::get_voltage_mv()?;
paho_mqtt::Client::new(String::from("192.168.1.1"));
serialport::available_ports()?;
Ok(())
}
If I try to put the ?
operator at the end of the paho_mqtt
line, I get the following build error:
^ the trait `From<paho_mqtt::Error>` is not implemented for `std::io::Error`
I acknowledge that I could use anyhow
crate - but it would be an even more amazing solution to have From<paho_mqtt::Error>
implemented for std::io::Error
. :)
Oh, I'm sorry. I misread your first post.
I was thinking of it the other way around.... With the existing code you can create an mqtt_paho::Error
from a std::io::Error
, but not going in the other direction. So potentially, if you made main() return a paho_mqtt::Result<()>
it might work, though you might need to coerce some of the errors like from hm305p
to behave properly.
But your suggestion sounds reasonable. (Technically MQTT is an I/O library and its errors can be considered I/O errors, right?) I hadn't even thought of it. And the implementation you suggest looks like the proper way to do it.
I'll test it out.
But have you tried the anyhow crate? It's a good way to deal with heterogenous errors in a Rust application, like the one you show. Even if I get the suggested fix in, anyhow
may still be useful to easily add a context to the errors. Something like:
use anyhow::{Result, Context};
use std::process::Command;
fn main() -> Result<()> {
hm305p::get_voltage_mv()
.context("Couldn't retrieve voltage")?;
serialport::available_ports()?;
let _cli = paho_mqtt::Client::new("192.168.1.1")
.context("Error connecting to MQTT broker")?;
Command::new("ping").arg("192.168.1.1").output()
.context("Failed to run the 'ping' command")?;
let _ = chrono::Duration::seconds(-5).to_std();
Ok(())
}
On my machine, I get:
$ ./target/debug/result
Error: Couldn't retrieve voltage
Caused by:
Cannot find power supply
Oh, and of course you could just catch a generic error if you didn't want to add the anyhow
crate:
use std::{
error::Error,
process::Command,
};
fn main() -> Result<(), Box<dyn Error + 'static>> {
Command::new("ping").arg("192.168.1.1").output()?;
chrono::Duration::seconds(-5).to_std();
hm305p::get_voltage_mv()?;
paho_mqtt::Client::new(String::from("192.168.1.1"));
serialport::available_ports()?;
Ok(())
}
Added to the develop
branch. I'll go out with the next release.
Yaaay! Thank you!! 😃💚
Firstly: Thank you for this crate. :)
It would be helpful if
From<Error> for io::Error
was implemented, so that applications using this crate can use the?
operator on both crateResult
s andstd::io::Result
s.I think the implementation would be performed in
errors.rs
and would look as follows (perhaps with even morematch
cases filled in):I tested this locally with my own code, and it does indeed allow me to use the
?
operator onResult
s from this crate.