1

我正在尝试使用 Iron 框架在 Rust 中构建一个简单的后端。这个处理程序只是应该返回某个文件的内容,我可以让它正常工作,unwrap()但我想尝试做正确的错误处理。这就是我想象的样子:

fn get_content(res: &mut Request) -> IronResult<Response> {
    let mut id = String::new();
    res.body.read_to_string(&mut id).unwrap();

    let file_path_string = &("../content/".to_string() + &id + ".rdt");

    // TODO: Error handling
    match File::open(file_path_string) {
        Ok(f) => {
            let mut s = String::new();
            f.read_to_string(&mut s);
            Ok(Response::with(((status::Ok), s)))
        }
        Err(err) => Err(Response::with(((status::InternalServerError), "File not found")))
    };
}

这会引发错误not all control paths return a value [E0269],这很好。但是如果我在匹配部分之后添加一个响应:

match File::open(file_path_string) {
    Ok(f) => {
        let mut s = String::new();
        f.read_to_string(&mut s);
        Ok(Response::with(((status::Ok), s)))
    }
    Err(err) => Err(Response::with(((status::InternalServerError), "File not found")))
};

Err(Response::with(((status::InternalServerError), "File not found")))

相反,我收到错误消息:

expected `iron::error::IronError`,
    found `iron::response::Response`
(expected struct `iron::error::IronError`,
    found struct `iron::response::Response`) [E0308]
src/main.rs:95        
Err(Response::with(((status::InternalServerError), "File not found")))

我认为问题在于 Rust Err 和 Iron Err 之间的冲突?不过我不确定。而且我过去没有做过太多的 Web 开发(或 Rust),所以对代码的任何反馈也很感激!

更新:我认为这更像是“生锈方式”吗?但我不确定

fn get_content(res: &mut Request) -> IronResult<Response> {
    let mut id = String::new();
    res.body.read_to_string(&mut id).unwrap();

    let file_path_string = &("../content/".to_string() + &id + ".rdt");

    // TODO: Error handling
    let f;
    match File::open(file_path_string) {
        Ok(file) => f = file,
        Err(err) => Err(HttpError::Io(err))
    };
    let mut s = String::new();
    f.read_to_string(&mut s);
    Ok(Response::with(((status::Ok), s)))
}

在错误处理中包含代码似乎很奇怪,因为read_to_string还需要注意,这会造成错误处理的嵌套混乱?然而,这些匹配的手臂显然是不兼容的类型,所以它不会工作......有什么建议吗?

4

1 回答 1

2

AnOk()需要一个Response,但 anErr()需要一个IronError

因此,您的电话在aErr(...)时无效!...Response

如何纠正它?那么第一步是,你必须创建一个IronError发送回来。我相信(不熟悉 Iron)Iron 会自动生成适当的错误代码,而这不是你的工作。在文档中,我们发现一种关键类型实现IronError

pub enum HttpError {
    Method,
    Uri(ParseError),
    Version,
    Header,
    TooLarge,
    Status,
    Io(Error),
    Ssl(Box<Error + 'static + Send + Sync>),
    Http2(HttpError),
    Utf8(Utf8Error),
    // some variants omitted
}

我看不到一个允许像“找不到文件”这样的任意字符串的。但是,您的用例是 IO 故障之一,对吧?HttpError::Io因此,与std::IoError您从以下位置返回的内容一起使用是有意义的File::open()

match File::open(file_path_string) {
    Ok(f) => {
        let mut s = String::new();
        f.read_to_string(&mut s);
        Ok(Response::with(((status::Ok), s)))
    }
    Err(err) => Err(HttpError::Io(err))
};

顺便说一句,它还修复了您的“TODO:错误处理”!多漂亮!

(代码未经测试,如果编译失败请随时编辑)

于 2016-04-03T09:54:23.430 回答