Distinguish between implementation errors (invariant violations) and expected failure cases. For implementation errors that should never occur, use `unreachable!()` with explanatory comments rather than generic `panic!()` or `todo!()`. For expected failure modes, return proper error types with informative messages.
Distinguish between implementation errors (invariant violations) and expected failure cases. For implementation errors that should never occur, use unreachable!()
with explanatory comments rather than generic panic!()
or todo!()
. For expected failure modes, return proper error types with informative messages.
Implementation invariant violations:
// Good: Clear explanation with unreachable!()
if parsed != incr {
unreachable!("Parsing invariant violated: expected {} parsed digits, got {}", incr, parsed);
}
// Bad: Using todo() for cases that should never occur
match inner_fn {
IRBitwiseFunction::And => (new_bitwise_and_reduction(get_dt(input)?), input),
IRBitwiseFunction::Or => (new_bitwise_or_reduction(get_dt(input)?), input),
IRBitwiseFunction::Xor => (new_bitwise_xor_reduction(get_dt(input)?), input),
_ => todo!(), // Should be unreachable!() if this case can't happen
}
Expected failures:
// Good: Informative error with context
if ac.is_aggregated() {
polars_bail!(InvalidOperation: "cannot slice() an aggregated value")
}
// Good: Using try_ methods with ? operator to propagate errors
offset_fn(&Duration::try_parse(offset)?, timestamp, time_zone).map(Some)
Document error conditions with appropriate doc comments:
/// # Panics
/// Panics if the parsing invariant is violated.
/// # Errors
/// Returns an error if the input cannot be parsed as a valid timestamp.
In debug builds, use debug_assert!()
for checks that shouldn’t affect release performance, but always check critical invariants in both debug and release builds.
Enter the URL of a public GitHub repository