Common Standard Macros
eprintln!
The eprintln! macro (along with its no-newline companion eprint!) writes formatted diagnostic, warning, or error messages to the process's standard error stream (stderr, file descriptor 2) instead of standard output (stdout, file descriptor 1).
Why Diagnostic Output Belongs on stderr
In command-line tools and Unix pipelines, separating data output (stdout) from human diagnostics (stderr) prevents warnings, progress bars, or error messages from corrupting piped or redirected structured output:
$ my_tool --input data.csv > results.json
│
├── println!("{json}") ─┴─> Redirected into `results.json` (fd 1: stdout)
└── eprintln!("WARN..") ───> Printed on user's terminal screen (fd 2: stderr)
| Macro | Target Stream | File Descriptor | Buffering | Typical Use Case |
|---|---|---|---|---|
println! / print! |
io::stdout() |
1 |
Line-buffered (TTY) or block-buffered (pipe/file) | Program output, JSON/CSV data, requested results |
eprintln! / eprint! |
io::stderr() |
2 |
Unbuffered / direct | Errors, warnings, progress logs, debug traces |
Reporting Errors and Warnings to stderr
fn parse_config_port(raw: &str) -> u16 {
match raw.parse::<u16>() {
Ok(port) => port,
Err(err) => {
eprintln!("warning: invalid port '{raw}' ({err}); falling back to 8080");
8080
}
}
}
fn main() {
let port = parse_config_port("not_a_number");
// Data output goes to stdout:
println!("{{\"port\": {port}}}");
}
warning: invalid port 'not_a_number' (invalid digit found in string); falling back to 8080
{"port": 8080}
Exiting with a Non-Zero Status Code After eprintln!
In CLI binaries, fatal user-facing errors are printed with eprintln! followed by std::process::exit(1) (or by returning std::process::ExitCode::FAILURE from main()):
use std::process::ExitCode;
fn run_app(args: &[&str]) -> Result<(), &'static str> {
if args.is_empty() {
return Err("missing required <input_file> argument");
}
println!("Processing {}", args[0]);
Ok(())
}
fn main() -> ExitCode {
if let Err(msg) = run_app(&["dataset.parquet"]) {
eprintln!("error: {msg}");
return ExitCode::FAILURE;
}
ExitCode::SUCCESS
}
Processing dataset.parquet