创建新错误时重用现有错误的描述

时间:2015-03-20 03:01:37

标签: error-handling rust

我在Rust中有以下代码,它不能编译,但显示了我想要做的事情。

    pub fn parse(cursor: &mut io::Cursor<&[u8]>) -> io::Result<Ack> {
        use self::byteorder::{BigEndian, ReadBytesExt};
        use self::core::error::Error;

        match cursor.read_u16::<BigEndian>() {
            Err(byteorder::Error::Io(error)) => Err(error),
            Err(error) =>
                Err(io::Error::new(io::ErrorKind::Other, error.description(),
                                   None)),
            Ok(value) => Ok(Ack { block_number: value })
        }
    }

本质上,我想获取byteorder库返回的错误的错误描述,并使用它来创建错误的描述,我将传回给我的库用户。此操作因packets.rs:166:58: 166:63 error:错误does not live long enough而失败,我明白了原因。

byteorder库通过在std::io::Result构造函数中包装byteorder::Error::Io来解决此问题。但是,我不想采用这种方式,因为我必须定义包含std::io::Errorbyteorder::Error的错误类型。在我看来,我的用户不应该知道或不关心我使用字节顺序库,它不应该成为我的界面的一部分。

我是Rust新手,还不知道语言和设计的习语和最佳实践。我可以选择处理这个问题吗?

2 个答案:

答案 0 :(得分:1)

您的问题实际上是io::Error::new()的第二个参数是&'static str,而byteorder::Error::description()返回&'a str,其中'a是有效期错误对象本身的值小于'static。因此,您无法将其用于io::Error的说明。

最简单的解决方法是将byteorder::Error说明移至detail的{​​{1}}字段:

io::Error

但是,您应该认真考虑制作一个自定义包装器错误类型,它封装了所有&#34;下游&#34;错误。使用正确编写的FromError实例,您应该能够编写类似

的内容
Err(error) =>
    Err(io::Error::new(
        io::ErrorKind::Other,
        "byteorder error",
        Some(error.description().to_string())
    )),
而不是你的整场比赛。自定义错误包装器也可以帮助您在程序增长时使用更多&#34;下游&#34;出现错误来源 - 您可以添加新的枚举变体和/或try!(cursor.read_u16::<BigEndian>() .map(|value| Ack { block_number: value })) 实现来支持这些新错误。

答案 1 :(得分:0)

我无法测试您的代码,所以我无法确定。 ref关键字不够用吗?

Err(byteorder::Error::Io(ref error)) => Err(error),