We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Errors Are Values step 24 of 24
Documenting failure: # Errors and # Panics
Take the AppError / parse_record code you already wrote and document its
failure modes. The behaviour must not change — every test case is the same
as before, so you cannot pass this by editing the logic.
pub fn parse_record(line: String) -> Result<(i32, f64), AppError>
pub fn record_ratio(line: String) -> f64
record_ratio is new: it parses a record and returns value / count. It
panics on a malformed record and on a zero count — deliberately, because it is
a convenience wrapper for input a caller has already validated.
The gate
#![deny(
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::missing_safety_doc
)]
and the starter, which is behaviourally perfect, does not build:
error: docs for function returning `Result` missing `# Errors` section
|
| pub fn parse_record(line: String) -> Result<(i32, f64), AppError> {
|
error: docs for function which may panic missing `# Panics` section
|
| pub fn record_ratio(line: String) -> f64 {
Two sections, written as ordinary Markdown headings inside a /// doc comment:
/// One-line summary.
///
/// # Errors
///
/// Returns [`AppError::Empty`] if the line is blank once trimmed, …
pub fn parse_record(line: String) -> Result<(i32, f64), AppError> { … }
missing_panics_doc detects panic!, unwrap, expect and assert! in the
body. record_ratio has two of those, so it needs a # Panics section saying
what triggers them.
Why this is a real gate and not bureaucracy
Most professional Rust codebases turn these two lints on, and the reason is not
tidiness. A Result in a signature says that a function can fail; nothing in
the type says when, or which variant to expect for which input. That
information exists only in the author’s head at the moment they write the
function, and the # Errors section is the only place it can be written down
before it evaporates.
There is a second, sneakier benefit. Writing the section forces you to
enumerate your own failure modes in prose — and an error enum that has grown
incoherent is very obvious when you try. If your # Errors section reads
“returns Error::Other if something goes wrong”, you have just discovered that
your error type is not carrying its weight.
The same for # Panics. Every panic in a library is a contract term: “if you
call me like this, I will take your process down”. Undocumented, it is a
landmine. Documented, it is an API.
What the lint can and cannot check
Be clear-eyed about this: the lint only checks that the section exists. It
does not read it. # Errors\n\nSometimes. passes. That is why the behavioural
test cases are still here, and why “keep the docs accurate” remains a human
job.
There is also a trap that costs people twenty minutes: both lints only apply
to pub items. Remove pub from parse_record and every diagnostic
vanishes — not because the docs got better, but because clippy stopped
caring. If you are turning these on in a real crate and see zero warnings,
check your visibility before you congratulate yourself.
Conventions worth copying
-
The first paragraph is the summary and should be one sentence.
too_long_first_doc_paragraph(pedantic) exists because a wall of text there ruins the module index page, where only that first paragraph is shown. -
Link to types with intra-doc links:
[`AppError::Empty`]renders as a real hyperlink in rustdoc and breaks the build if the path is wrong. -
# Errors,# Panicsand# Safetyare the conventional headings, in that order, after the summary and any examples.# Safetyis forunsafe fn—missing_safety_docis on by default, andunnecessary_safety_docfires if you add one to a safe function. -
Document the enum variants too.
missing_docs_in_private_itemsis a restriction lint and off here, but a# Errorssection that names variants is much more useful when clicking through to the variant tells you more.
Notes
-
empty_docscatches a///with nothing after it;doc_lazy_continuationcatches a list item whose continuation line is not indented, which silently ends the list in the rendered output. -
suspicious_doc_commentscatches//!used where///was meant — an inner doc comment placed just before an item documents the enclosing module instead, and the resulting rustdoc is confusing rather than broken. -
record_ratiokeeps its#[must_use]: it is a pure function returning a number, so calling it and dropping the result is meaningless.
Remember the grade is compile + tests + clippy -D warnings.
Stuck?
Rust reference solution
Sign in to attempt this problem and reveal the reference solution.