如果结果 returns Err(_),我希望整个函数 return 出现 HTTP 请求错误
If a Result returns Err(_), I want the whole function to return a HTTP request error
我正在尝试使用 Iron 框架在 Rust 中构建一个简单的后端。这个处理程序应该 return 某个文件的内容,我可以让它与 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 相关的开发),所以对代码的任何反馈也很感激!
更新:我觉得这样更 "The Rust Way" 可以吗?但我不确定
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
也需要处理,这会造成错误处理的嵌套混乱?但是,这些匹配的手臂显然是不兼容的类型,所以它不会工作...有什么建议吗?
一个 Ok()
需要一个 Response
,但是一个 Err()
需要一个 IronError
。
因此当 ...
是 Response
!
时,您的呼叫 Err(...)
无效
如何纠正?那么第一步是,您必须创建一个 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
}
我看不到像 "file not found" 这样的任意字符串。但是,您的用例是 IO 故障之一,对吗?因此,将 HttpError::Io
与从 File::open()
:
返回的 std::IoError
一起使用是有意义的
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: error handling"!好漂亮!
(代码未经测试,编译失败请随时修改)
我正在尝试使用 Iron 框架在 Rust 中构建一个简单的后端。这个处理程序应该 return 某个文件的内容,我可以让它与 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 相关的开发),所以对代码的任何反馈也很感激!
更新:我觉得这样更 "The Rust Way" 可以吗?但我不确定
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
也需要处理,这会造成错误处理的嵌套混乱?但是,这些匹配的手臂显然是不兼容的类型,所以它不会工作...有什么建议吗?
一个 Ok()
需要一个 Response
,但是一个 Err()
需要一个 IronError
。
因此当 ...
是 Response
!
Err(...)
无效
如何纠正?那么第一步是,您必须创建一个 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
}
我看不到像 "file not found" 这样的任意字符串。但是,您的用例是 IO 故障之一,对吗?因此,将 HttpError::Io
与从 File::open()
:
std::IoError
一起使用是有意义的
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: error handling"!好漂亮!
(代码未经测试,编译失败请随时修改)