Skip to content

Error Handling

convert() returns Result<ConversionResult, ConversionError> in Rust. Every other binding maps the error to its native idiom: Python raises an exception, Go returns (result, error), Java throws a checked exception, and so on.

Non-fatal issues never produce an error. They accumulate in result.warnings and the call still succeeds.

Eight variants. All carry a String message except IoError, which wraps std::io::Error via #[from].

Variant Payload Cause
ParseError String Malformed HTML the parser could not recover from.
SanitizationError String Reserved for binding use. The core library never constructs this variant today — there is no sanitization pass; convert() does not reject or clean unsafe markup.
ConfigError String ConversionOptions contains an invalid combination (unknown format string, out-of-range width, etc.).
IoError std::io::Error Reading a file, reading stdin, or writing output failed.
Panic String A panic was caught inside the conversion core. The FFI boundaries catch unwinds so other bindings see a normal error instead of a crash.
InvalidInput String Binary/corrupted data detected (compressed data, excess NUL or control bytes, undeclared UTF-16), or decoding failure for a wrong encoding setting. There is no input size cap — see Security.
Visitor String A visitor callback returned VisitResult::Error(...). Only compiled with features = ["visitor"]. Rust users on default features never see this variant.
Other String Catch-all for anything that does not fit above.

result.warnings is a Vec<ProcessingWarning>. Each warning has a kind and a message. The CLI prints them to stderr with --show-warnings; in library code, iterate and log them yourself.

Warnings are the right place to surface “this was weird but the conversion worked” signals: skipped oversized images, unknown class attributes on code blocks, malformed table rows that were repaired. None of these halt the call.

use html_to_markdown_rs::convert;
use html_to_markdown_rs::error::ConversionError;
fn main() {
// Binary data (detected via magic bytes) is rejected before parsing.
let html = "%PDF-1.4 not actually HTML";
match convert(html, None) {
Ok(result) => println!("{}", result.content.unwrap_or_default()),
Err(ConversionError::InvalidInput(message)) => {
eprintln!("invalid input: {message}");
}
Err(ConversionError::ParseError(message)) => {
eprintln!("parse error: {message}");
}
Err(other) => eprintln!("conversion failed: {other}"),
}
}

The CLI hides warnings by default. Pass --show-warnings to print each one to stderr in the format Warning [<kind>]: <message>. The flag works with or without --json. See CLI: JSON Output.

Found a bug or mistake on this page?

If something here is wrong or out of date, open an issue on GitHub or contribute a fix via pull request.