Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better error handling and better Comments #409

Closed
wants to merge 24 commits into from

Conversation

Guelakais
Copy link
Contributor

A lot of error handling in the code is solved via if-queries, although you could also do it via match cases match cases are more idiomatic. There are still parts of the code that I don't quite understand. I have tried to comment everything I understand as much as possible.

Copy link
Collaborator

@esteve esteve left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Guelakais thanks for your PR. I don't like doing matches on booleans, it actually makes the code less readable. Could you just keep the comments? Thanks.

rosidl_runtime_rs/src/sequence.rs Outdated Show resolved Hide resolved
rosidl_runtime_rs/src/sequence.rs Outdated Show resolved Hide resolved
@Guelakais
Copy link
Contributor Author

@Guelakais thanks for your PR. I don't like doing matches on booleans, it actually makes the code less readable. Could you just keep the comments? Thanks.

I don't like that either. However, I am more of the opinion that an error-enum should be introduced anyway, which covers error handling better. The matches somehow serve as an aid to my thinking. A suggestion: If I haven't figured it out by Wednesday evening, I'll rebuild the entire PR clean and with comments only. Until then, we can also see whether the other PRs are running better.

@esteve
Copy link
Collaborator

esteve commented Jun 24, 2024

@Guelakais I'm not going to approve a PR that has code similar to this:

    fn clone(&self) -> Self {
        let mut seq = Self::default();
        match T::sequence_copy(self, &mut seq) {
            true => seq,
            _ => panic!("Cloning Sequence failed"),
        }
    }

it just does not make sense, plus there's no way to change the definition of this function because it's part of the Clone trait, you can't change it and expect to continue working. All the functions you've changed are functions defined in their respective traits, so you can't return an error-enum if it's not part of the function signature in the trait.

@Guelakais
Copy link
Contributor Author

@Guelakais I'm not going to approve a PR that has code similar to this:

    fn clone(&self) -> Self {
        let mut seq = Self::default();
        match T::sequence_copy(self, &mut seq) {
            true => seq,
            _ => panic!("Cloning Sequence failed"),
        }
    }

it just does not make sense, plus there's no way to change the definition of this function because it's part of the Clone trait, you can't change it and expect to continue working. All the functions you've changed are functions defined in their respective traits, so you can't return an error-enum if it's not part of the function signature in the trait.

Ok,

@Guelakais
Copy link
Contributor Author

I have finally learnt how to remove git commits from my history. That makes a lot of things easier.

Copy link
Contributor Author

@Guelakais Guelakais left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at it and edited it. The changes are currently being imported.

rosidl_runtime_rs/src/sequence.rs Outdated Show resolved Hide resolved
GueLaKais added 11 commits June 25, 2024 14:01
To be honest, I still don't understand exactly what's happening here. All I know is that it's at least somewhat understandable what's going on here.
To be honest, I still don't understand exactly what's happening here. All I know is that it's at least somewhat understandable what's going on here.
To be honest, I still don't understand exactly what's happening here. All I know is that it's at least somewhat understandable what's going on here.
To be honest, I still don't understand exactly what's happening here. All I know is that it's at least somewhat understandable what's going on here.
To be honest, I still don't understand exactly what's happening here. All I know is that it's at least somewhat understandable what's going on here.
GueLaKais added 3 commits June 25, 2024 14:16
To be honest, I still don't understand exactly what's happening here. All I know is that it's at least somewhat understandable what's going on here.
Copy link
Contributor Author

@Guelakais Guelakais left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the corresponding commit

@esteve esteve marked this pull request as draft June 26, 2024 08:28
@esteve
Copy link
Collaborator

esteve commented Jun 26, 2024

@Guelakais I'm moving this PR back to draft, let us know when you're done making changes and we'll review it.

@Guelakais Guelakais requested a review from esteve June 26, 2024 13:18
Copy link
Contributor Author

@Guelakais Guelakais left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could also be worse. It's ok.

@Guelakais
Copy link
Contributor Author

Yes, no, it's fine. I'm done with that so far.

@Guelakais Guelakais marked this pull request as ready for review June 26, 2024 18:30
Copy link
Collaborator

@maspe36 maspe36 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the rust doc convention for linking to items by name
https://doc.rust-lang.org/rustdoc/write-documentation/linking-to-items-by-name.html


In general, I think our documentation should follow this high level guideline

Short summary of the intention of the function/struct/modules

On success, does this.

If there is a failure, here is what we do.

More tokio inspriation
https://docs.rs/tokio/latest/tokio/io/trait.AsyncBufRead.html#tymethod.poll_fill_buf

Comment on lines +46 to +48
/// This implementation finalizes the `rcl_client_t` instance by calling `rcl_client_fini`.
/// It also acquires the entity lifecycle mutex to protect against the risk of global variables
/// in the rmw implementation being unsafely modified during cleanup.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is redundant with the safety section.

Comment on lines 119 to 120
// This uses pub(crate) visibility to avoid instantiating this struct outside
// [`Node::create_client`], see the struct's documentation for the rationale
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed this, this is actually just a plain comment — it won't be part of the generated docs.

Comment on lines +325 to +326
/// If the `take_response` method returns a `ClientTakeFailed` error, it is treated as a
/// spurious wakeup and is not considered an error.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of enumerating each possible result in the docs of many functions, consider just linking to RclrsError and in a future PR we can improve the docs for that.

Here is some inspiration from tokio
https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html

Comment on lines +318 to +323
/// Executes the client by taking a response from the underlying `rcl_client_t` instance
/// and handling it appropriately.
///
/// This method attempts to take a response from the client using `take_response`. If a response
/// is successfully taken, it is processed by either calling the associated callback or sending
/// the response to the associated future.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These sections could be combined and condensed. The docs for take_response already detail quite a bit about whats going on under the hood with the rcl handle.

This should say something along the lines of...

Get a response from the rcl handle via take_response and execute the associate callback or future.

pub fn steady() -> Self {
Self::make(ClockType::SteadyTime)
}

/// Creates a new Clock with `ClockType::RosTime` and a matching `ClockSource` that can be used
/// to update it
///
/// # Returns
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There really is no need for the # Returns section. Rustdoc already does a great job showcasing the function signature which will include the return type (with a link to it!).

Sometimes the function signature + name is sufficient documentation and anything we add is just noise.

@@ -489,11 +537,40 @@ impl Display for SequenceExceedsBoundsError {
)
}
}

/// Implements the `std::error::Error` trait for the `SequenceExceedsBoundsError` struct.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this comment, it duplicates the information in the line of code and doesn't provide any additional content.

@@ -463,14 +511,14 @@ impl<T: SequenceAlloc> Iterator for SequenceIterator<T> {
self.idx += 1;
Some(elem)
}

/// returns the remaining length of the sequence
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't really explain much. Here is some inspiration from the iterator trait
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.size_hint

Also, this is not something to be addressed in this PR but I wonder why Sequence doesn't actually implement iterator.

impl<T: SequenceAlloc> ExactSizeIterator for SequenceIterator<T> {
/// Returns the length of the sequence as unsigned integer.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to document this function, then the comment should expand on more than just the function signature.

Checkout the rustdocs for std::Vec::len

Comment on lines +542 to +570
/// Macro to provide default implementations for the `SequenceAlloc` trait for primitive types.
///
/// This macro generates an implementation of the `SequenceAlloc` trait for a given primitive type.
/// It defines three extern "C" functions (`$init_func`, `$fini_func`, and `$copy_func`) that are
/// linked from the "rosidl_runtime_c" library and used to initialize, finalize, and copy sequences
/// of the specified type.
///
/// The `sequence_init` function allocates space for the sequence and sets its size and capacity.
/// If the sequence's data pointer is null, it calls `$init_func` to allocate memory. Otherwise,
/// it writes zero bytes to the existing memory region.
///
/// The `sequence_fini` function finalizes the sequence by calling `$fini_func`.
///
/// The `sequence_copy` function copies the contents of one sequence to another by calling
/// `$copy_func`.
///
/// # Safety
///
/// The implementations of `sequence_init`, `sequence_fini`, and `sequence_copy` are marked as
/// `unsafe` because they call the corresponding extern "C" functions, which may have undefined
/// behavior if their preconditions are not met. However, the macro assumes that there are no
/// special preconditions for these functions.
///
/// # Arguments
///
/// * `$rust_type:ty` - The Rust type for which the `SequenceAlloc` trait should be implemented.
/// * `$init_func:ident` - The name of the extern "C" function used to initialize a sequence.
/// * `$fini_func:ident` - The name of the extern "C" function used to finalize a sequence.
/// * `$copy_func:ident` - The name of the extern "C" function used to copy a sequence.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even with cargo doc --document-private-items (or --all), this won't be picked up as a docstring by rust doc. So consider just making it a regular comment.

@@ -505,6 +582,21 @@ macro_rules! impl_sequence_alloc_for_primitive_type {
}

impl SequenceAlloc for $rust_type {
/// Initializes a sequence with a given size.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the docstrings in here will be picked up by rustdoc. I'd recommend trimming them down (the high level description and safety sections mainly) and turning them into regular comments.

@esteve
Copy link
Collaborator

esteve commented Aug 12, 2024

@Guelakais are you still interested in getting this PR merged? Could you please address @maspe36 's feedback? Thanks.

@Guelakais Guelakais closed this Oct 1, 2024
@Guelakais Guelakais deleted the better_error_handling branch October 1, 2024 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants