fix(NATSRS-003): Info::cluster field uses skip_serializing_if but is Option<ClusterInfo>, missing Option::is_none guard - #47
Conversation
…Option<ClusterInfo>, missing Option::is_none guard
There was a problem hiding this comment.
🦩 What this fix changed, finding by finding
5 finding(s) — 4 fixed (4 explained inline on the diff), 1 not fixed.
⚠️ Not fixed — needs human judgment
🔴 5. FromConsumer::try_from_consumer_config returns crate::Error (Box) instead of a typed Error — async-nats/src/jetstream/consumer/mod.rs:155
NOT FIXED: The finding requests changing FromConsumer::try_from_consumer_config to return a typed Result<Self, ConsumerConversionError> with a new ConsumerConversionErrorKind enum and ConsumerConversionError type alias. This cannot be done mechanically in a single file without: (a) knowing whether ConsumerConversionError/ConsumerConversionErrorKind should live in this file or a shared error module, (b) updating all downstream implementations of FromConsumer in pull/mod.rs and push/mod.rs (which are separate files not provided), and (c) updating all call sites. Changing only this file would break the trait implementations in the other files and cause compilation errors. A real fix requires coordinated changes across at least pull/mod.rs, push/mod.rs, and this file, plus introducing the new error types.
🤖 Prompt for AI agents
In async-nats/src/jetstream/consumer/mod.rs around line 155, address this code-review finding: FromConsumer::try_from_consumer_config returns crate::Error (Box<dyn Error>) instead of a typed Error<Kind>.
The finding requests changing `FromConsumer::try_from_consumer_config` to return a typed `Result<Self, ConsumerConversionError>` with a new `ConsumerConversionErrorKind` enum and `ConsumerConversionError` type alias. This cannot be done mechanically in a single file without: (a) knowing whether `ConsumerConversionError`/`ConsumerConversionErrorKind` should live in this file or a shared error module, (b) updating all downstream implementations of `FromConsumer` in `pull/mod.rs` and `push/mod.rs` (which are separate files not provided), and (c) updating all call sites. Changing only this file would break the trait implementations in the other files and cause compilation errors. A real fix requires coordinated changes across at least `pull/mod.rs`, `push/mod.rs`, and this file, plus introducing the new error types.
Make the minimal change that resolves the finding; do not refactor unrelated code.
| @@ -183,18 +183,18 @@ pub struct Info { | |||
| /// The number of messages pending delivery | |||
There was a problem hiding this comment.
🦩 🟠 ✅ Fixed — Info::cluster field uses skip_serializing_if but is Option, missing Option::is_none guard
FIXED: Changed #[serde(skip_serializing_if = "is_default")] to #[serde(default, skip_serializing_if = "Option::is_none")] on the cluster field (was line 183). This correctly uses Option::is_none as the skip guard for the Option<ClusterInfo> field.
| /// Indicates if any client is connected and receiving messages from a push consumer | ||
| #[serde(default, skip_serializing_if = "is_default")] | ||
| pub push_bound: bool, | ||
| #[cfg(feature = "server_2_11")] |
There was a problem hiding this comment.
🦩 🔴 ✅ Fixed — pause_remaining uses serde_nanos but is Option, must use serde_nanos::option
FIXED: Changed #[serde(default, with = "serde_nanos")] to #[serde(default, with = "serde_nanos::option", skip_serializing_if = "Option::is_none")] on the pause_remaining field (was line 191). This uses the correct serde_nanos::option adapter for Option<Duration> and adds the missing skip_serializing_if guard.
| /// Indicates if any client is connected and receiving messages from a push consumer | ||
| #[serde(default, skip_serializing_if = "is_default")] | ||
| pub push_bound: bool, | ||
| #[cfg(feature = "server_2_11")] |
There was a problem hiding this comment.
🦩 🟠 ✅ Fixed — pause_remaining Option field missing skip_serializing_if = "Option::is_none"
FIXED: The skip_serializing_if = "Option::is_none" guard was added to pause_remaining as part of the same attribute change described in finding 2 above.
| /// Information about the consumer's cluster | ||
| #[serde(skip_serializing_if = "is_default")] | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub cluster: Option<ClusterInfo>, |
There was a problem hiding this comment.
🦩 🔴 ✅ Fixed — Info::paused field doc comment is placed after the cfg attribute, not before it
FIXED: Moved the doc comment /// Indicates if the consumer is paused to before the #[cfg(feature = "server_2_11")] attribute on the paused field (was line 187). The doc comment now precedes all attributes, which is the correct Rust ordering.
Closes findings from rule NATSRS-003 — Info::cluster field uses skip_serializing_if but is Option, missing Option::is_none guard.
Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.
async-nats/src/jetstream/consumer/mod.rs:183async-nats/src/jetstream/consumer/mod.rs:191async-nats/src/jetstream/consumer/mod.rs:191async-nats/src/jetstream/consumer/mod.rs:187async-nats/src/jetstream/consumer/mod.rs:155What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.
Run: https://product-hub.flamingo.so/admin/code-review
Run id:
1bff4c8b-6382-4a91-9010-0698bc64d01bMerging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.