Я пытаюсь использовать инфраструктуру Iron для создания простого бэкэнда в Rust. Этот обработчик должен только возвращать содержимое определенного файла, и я могу заставить его работать правильно с unwrap()
, но я хочу попытаться выполнить правильную обработку ошибок. Это, как я предположил бы, что это будет выглядеть так:Если результат возвращает Err (_), я хочу, чтобы вся функция возвращала ошибку HTTP-запроса.
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 и железного Err? Хотя я не уверен. И в прошлом я не делал много веб-разработки (или 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
также необходимо позаботиться и что бы создать вложенную беспорядок обработки ошибок? Однако эти совпадающие руки, очевидно, несовместимы, поэтому они не сработают ... никаких предложений?
ли идиоматически правильно сделать остальную часть кода части внутренней обработки ошибок? Учитывая, что мне нужно обработать результат '' 'read_to_string''', не создаст ли он вложенный беспорядок обработки ошибок? – mnordber
Возможно, было бы идиоматическим, чтобы сначала увидеть, применим ли макрос 'try!' (Я не знаю, относится ли это к типам ошибок Iron и/или подписи вашей функции.) Если это не так, хорошее обходное решение будет состоять в следующем: 'let what_you_want = match ... {...}' и 1. сделайте конец ветки Ok с what_you_want 2. ранним возвратом из ветви Err. Таким образом, вы можете продолжить работу без гнезда. Собственно, это философия, стоящая за «try!». – mdup
Да, я пытался использовать 'try!'сначала, но было какое-то столкновение с пакетом Iron. Является ли решение просто отказаться от «try!» Или вы можете обойти это? Я также попробовал подход 'let what_you_want = match', но оказался в беспорядке с оружием, не имеющим соответствующих типов. Что такое раннее возвращение? Это просто добавление возврата? 'return Err (HttpError :: Io (err))'? Потому что проблема, которую я получаю, заключается в том, что я возвращаю «гипер :: ошибка: ошибка», но она выдает «iron :: error :: IronError» ... – mnordber