From: Daniel Sedlak <daniel@sedlak.dev>
To: Dirk Behme <dirk.behme@de.bosch.com>, rust-for-linux@vger.kernel.org
Cc: ojeda@kernel.org
Subject: Re: [PATCH] rust: error: Extend the Result documentation
Date: Tue, 7 Jan 2025 13:16:59 +0100 [thread overview]
Message-ID: <75dab379-af4b-4591-ba84-3807918c6e8f@sedlak.dev> (raw)
In-Reply-To: <20250107062134.2981602-2-dirk.behme@de.bosch.com>
On 1/7/25 7:21 AM, Dirk Behme wrote:
> Extend the Result documentation by some guidelines and examples how
> to handle Result error cases gracefully. And how to not handle them.
>
> Link: https://lore.kernel.org/rust-for-linux/CANiq72keOdXy0LFKk9SzYWwSjiD710v=hQO4xi+5E4xNALa6cA@mail.gmail.com/
> Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
> ---
> rust/kernel/error.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 66 insertions(+)
>
> diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs
> index 0b01975c2286c..456487d4a8ed8 100644
> --- a/rust/kernel/error.rs
> +++ b/rust/kernel/error.rs
> @@ -256,6 +256,72 @@ fn from(e: core::convert::Infallible) -> Error {
> /// Note that even if a function does not return anything when it succeeds,
> /// it should still be modeled as returning a `Result` rather than
> /// just an [`Error`].
> +///
> +/// Calling a function that returns [`Result`] needs the caller to handle
> +/// the returned [`Result`].
> +///
> +/// This can be done "manually" by using [`match`](https://doc.rust-lang.org/reference/expressions/match-expr.html)
> +/// Using [`match`](https://doc.rust-lang.org/reference/expressions/match-expr.html) to decode
> +/// the [`Result`] is similar to C where all the return value decoding and the
> +/// error handling is done explicitly by writing handling code for each
> +/// error to cover. Using [`match`](https://doc.rust-lang.org/reference/expressions/match-expr.html)
> +/// the error and success handling can be implemented in all detail as required.
> +/// For example (inspired by [samples/rust/rust_minimal.rs](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/rust/rust_minimal.rs)):
> +/// ```
> +/// fn example () -> Result {
> +/// let mut numbers = KVec::new();
> +/// match numbers.push(72, GFP_KERNEL) {
> +/// Err(e) => {pr_err!("Error pushing 72: {:?}", e); return Err(e.into());},
> +/// Ok(()) => (), // Do nothing, continue
> +/// }
> +/// match numbers.push(108, GFP_KERNEL){
> +/// Err(e) => {pr_err!("Error pushing 108: {:?}", e); return Err(e.into());},
> +/// Ok(()) => (), // Do nothing, continue
> +/// }
> +/// match numbers.push(200, GFP_KERNEL){
> +/// Err(e) => {pr_err!("Error pushing 200: {:?}", e); return Err(e.into());},
> +/// Ok(()) => (), // Do nothing, continue
> +/// }
> +/// Ok(())
> +/// }
> +/// ```
> +/// Instead of the verbose [`match`](https://doc.rust-lang.org/reference/expressions/match-expr.html)
> +/// the [`?`](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator)-operator
> +/// or [`unwrap()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap)/
> +/// [`expect()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.expect)
> +/// can be used to handle the [`Result`] "automatically". However, in the kernel
> +/// context, the usage of [`unwrap()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap) or
> +/// [`expect()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.expect) has a side effect which is often
> +/// not wanted: The [`panic`](https://docs.kernel.org/driver-api/basics.html#c.panic) called when using
> +/// [`unwrap()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap) or
> +/// [`expect()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.expect). While the
> +/// console output from [`panic`](https://docs.kernel.org/driver-api/basics.html#c.panic) is
> +/// nice and quite helpful for debugging the error, stopping the whole Linux system due to the kernel
> +/// panic is often **not** desired:
> +/// ```
> +/// fn example () -> Result {
> +/// let mut numbers = KVec::new();
> +/// numbers.push(72, GFP_KERNEL).expect("Error pushing 72"); // Panics the system in case of an error
> +/// numbers.push(108, GFP_KERNEL).expect("Error pushing 108"); // Panics the system in case of an error
> +/// numbers.push(200, GFP_KERNEL).expect("Error pushing 200"); // Panics the system in case of an error
> +/// Ok(())
> +/// }
> +/// ```
> +/// Instead [`unwrap_or()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or),
> +/// [`unwrap_or_else()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_else) or
> +/// [`unwrap_or_default()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_default)
> +/// can be used. But in consequence, using the [`?`](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator)-operator
> +/// is often the best choice to handle [`Result`] in a non-verbose way as done in
> +/// [samples/rust/rust_minimal.rs](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/rust/rust_minimal.rs)):
> +/// ```
> +/// fn example () -> Result {
> +/// let mut numbers = KVec::new();
> +/// numbers.push(72, GFP_KERNEL)?;
> +/// numbers.push(108, GFP_KERNEL)?;
> +/// numbers.push(200, GFP_KERNEL)?;
> +/// Ok(())
> +/// }
> +/// ```
> pub type Result<T = (), E = Error> = core::result::Result<T, E>;
>
> /// Converts an integer as returned by a C kernel function to an error if it's negative, and
You are duplicating some links. You can take advantage of positional
parameters [1] and put the URLs at the end of the comment, which would
solve the link duplication and IMO increase readability, because
scattered links in the comments decreases readability a lot (in non HTML
version).
[1]:
https://doc.rust-lang.org/rustdoc/write-documentation/linking-to-items-by-name.html#valid-links
Daniel
next prev parent reply other threads:[~2025-01-07 12:17 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-07 6:21 [PATCH] docs: rust: Add error handling sections Dirk Behme
2025-01-07 6:21 ` [PATCH] rust: error: Extend the Result documentation Dirk Behme
2025-01-07 12:16 ` Daniel Sedlak [this message]
2025-01-07 12:54 ` Alice Ryhl
2025-01-12 13:10 ` Miguel Ojeda
2025-01-12 13:45 ` [PATCH] docs: rust: Add error handling sections Miguel Ojeda
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=75dab379-af4b-4591-ba84-3807918c6e8f@sedlak.dev \
--to=daniel@sedlak.dev \
--cc=dirk.behme@de.bosch.com \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox