Skip to content

Commit f306428

Browse files
committed
Clarify attribute put null-guard rule
1 parent f7cd5a1 commit f306428

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

.github/agents/code-review-and-fix.agent.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ Auto-fix boundaries:
240240
- redundant `if (value != null)` guards around `AttributesBuilder.put()` calls —
241241
`put` is a no-op for null values, so remove the conditional and pass the value
242242
directly (same for span, log, and metrics attribute setters).
243+
Apply this only when the guarded value can be passed through directly to the
244+
attribute setter. If the null check is guarding a dereference or other derived
245+
computation, keep the explicit guard instead of rewriting it into a ternary
246+
expression just to pass `null` to `put()`.
243247
**Exception**: when the `AttributeKey` is typed as `Long` and the source value is
244248
`Integer`, the generic overload cannot match (`Integer ≠ Long`), so Java resolves
245249
to the `int` convenience overload `put(AttributeKey<Long>, int)` via auto-unboxing.
@@ -248,6 +252,8 @@ Auto-fix boundaries:
248252
When the value type **matches** the `AttributeKey` type parameter (e.g.,
249253
`Boolean``AttributeKey<Boolean>`, `Long``AttributeKey<Long>`), the generic
250254
`@Nullable T` overload is selected directly, null is safe, and the guard is redundant.
255+
For example, keep `if (view != null) { attributes.put(KEY, view.getClass().getName()); }`
256+
as-is; do not rewrite it to `attributes.put(KEY, view == null ? null : view.getClass().getName())`.
251257
- defensive `if (param == null)` checks on parameters not annotated `@Nullable`
252258
these contradict the framework's nullability contract; remove the guard. Conversely,
253259
add `@Nullable` to a parameter only when `null` is actually passed by callers or an

.github/agents/knowledge/general-rules.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ All `put` / `setAttribute` methods on `AttributesBuilder`, `Span`, `SpanBuilder`
156156
`LogRecordBuilder` are no-ops when the value is `null` (upstream SDK guarantee).
157157
Do not wrap these calls in `if (value != null)` guards — pass the value directly.
158158

159+
This rule applies only when the guarded value can be passed through directly to the
160+
attribute setter. If the null check is guarding a dereference or other derived
161+
computation, keep the explicit guard instead of rewriting it into a ternary
162+
expression just to feed `null` to `put()`.
163+
159164
**Exception — `AttributeKey<Long>` with `Integer` value**: the only primitive-typed
160165
overload on these interfaces is a convenience method that accepts `int`:
161166

@@ -190,6 +195,16 @@ Preferred:
190195
attributes.put(SOME_KEY, getSomething());
191196
```
192197

198+
Do **not** flag (the guard is preserving a safe dereference and is clearer than a
199+
ternary rewrite):
200+
201+
```java
202+
View view = modelAndView.getView();
203+
if (view != null) {
204+
attributes.put("spring-webmvc.view.type", view.getClass().getName());
205+
}
206+
```
207+
193208
Also flag (the guard is unnecessary — types match, generic overload handles null):
194209

195210
```java

0 commit comments

Comments
 (0)