Rust
Adding context
Add context to errors with anyhow::Context.
Adding context
The message "invalid digit found in string" doesn't say what failed. A good error explains what was being done when it failed. In anyhow there are context and with_context for this:
use anyhow::{Context, Result};
fn port_oku(s: &str) -> Result<u16> {
s.parse::<u16>()
.with_context(|| format!("port okunamadı ({s})"))
}
// error: port okunamadı (99999)
// Caused by: number too large to fit in target type
Since with_context takes a closure, the message is produced only in the error case.
Context with std
Without an external crate, the same effect is achieved with map_err: you combine the lower error and the context into one message:
fn port_oku(s: &str) -> Result<u16, String> {
s.parse::<u16>()
.map_err(|e| format!("port okunamadı ({s}): {e}"))
}
println!("{:?}", port_oku("8080")); // Ok(8080)
This turns the lower error into text; to keep the chain, we'll look at the source() method in the next lesson.
Exercise Error with context
Write the port_oku function above with map_err. Print the result for "8080" with {:?} and the error for "99999" as plain text, on separate lines.
Show example solution
fn port_oku(s: &str) -> Result<u16, String> {
s.parse::<u16>()
.map_err(|e| format!("port okunamadı ({s}): {e}"))
}
fn main() {
println!("{:?}", port_oku("8080"));
if let Err(e) = port_oku("99999") {
println!("{}", e);
}
}
Test yourself
-
What should a context message mostly include?
- The line number
- The user's name
- Nothing; the lower error is enough
- The operation and the relevant input (file name, key, value)
Show answer
The operation and the relevant input (file name, key, value) — The user should be able to find the problem from the message: "ayar.toml okunamadı" makes sense together with "No such file".
-
Lazy context
s.parse::<u16>()
.____(|| format!("port okunamadı ({s})"))
Show answer
s.parse::<u16>()
.with_context(|| format!("port okunamadı ({s})"))
-
Input and port_oku result
- "8080"
- Ok(8080)
- "99999"
- number too large ...
- "abc"
- invalid digit ...
- ""
- cannot parse ... empty string
Next lesson: Summary - Advanced error handling