Тыкаю руст, вот дошел до момента, когда хочется удобно залогать ошибку, которая выпала где-то внутри.
Примерный код:
fn main() {
let args: Vec<String> = ...
let res = doSmth(args);
match res {
Ok(val) => println!("Result: {}", val),
Err(err) => println!("Error: {}", err)
}
}
fn doSmth(args: Vec<String>) -> Result<String, ParseError> {
let v1 = parse(args[0]);
...
let v2 = parse(args[1]);
...
let v3 = parse(args[2]);
...
}
fn parse(v: String) -> Result<String, ParseError> {
...
}
Вот это всё прекрасно работает но я получаю только ParseError без уточнения места где оно выпало. Поскольку у меня в коде 3 точки где происходит парсинг то это может быть любая из них и как потом это отлаживать?
Есть вариант упасть в панику сразу, но чтобы всё было красиво нужен RUST_BACKTRACE=1
да и падать на месте совсем не хочется, хочется человеческий еррор.
На данный момент наклепал макрос, который создает кастомный еррор используя file!()
и line!()
и ловлю его.
Что-то вроде
fn parse(v: String) -> Result<String, MySuperPuperError> {
...
if !parsed {
throw!("Parsing Error");
}
}
fn doSmth(args: Vec<String>) -> Result<String, MySuperPuperError> {
...
let v1 = catch!(parse(args[0]));
let v2 = catch!(parse(args[1]));
let v3 = catch!(parse(args[2]));
...
}
fn main() {
...
Err(err) => println!("Error: {} at {}", err.message, err.position)
...
}
Я предполагаю, что кто-то уже должен был придумать что-то подобное, но я пока не нашел ничего чем было бы удобно пользоваться. Видел error_chain но он всё равно какой-то неудобный.