Commit a891ef8
authored
build(flake8): Add S019 rule banning reserved LogRecord keys in logging extra= (#117562)
## Summary
Passing a reserved `LogRecord` attribute (`name`, `message`, `args`,
`module`, …) as a key in a logging `extra=` dict raises `KeyError:
"Attempt to overwrite 'X' in LogRecord"` **at runtime**, when the log
line actually fires. Nothing static catches it — it passes ruff, mypy,
and a human skim — and it recently caused a silent production incident
in preprod snapshots (the log call meant to aid debugging was the thing
that crashed; see #117550).
This adds a custom **S019** flake8 rule (Sentry's `S###` family in
`tools/flake8_plugin.py`) that flags this class before runtime, and
fixes the only two existing violations it surfaces repo-wide.
This follows up a review question on #117550 ("can this class of problem
be prevented before runtime?").
## Changes
- **S019 rule** (`tools/flake8_plugin.py`): flags `logger.<level>(...,
extra={...})` calls whose `extra` dict has a literal string key
colliding with a reserved `LogRecord` attribute. Auto-registered via the
existing `S=` prefix plugin (no config change).
- **`test_S019`** (`tests/tools/test_flake8_plugin.py`): covers
`name`/`message` hits, a non-reserved key (ok), and a dynamic
`extra=var` (not flagged).
- **Fixes for the two surfaced violations:**
- `hybridcloud/apigateway/proxy.py`: `"message"` → `"error"` in a
breaker-config warning (would have crashed when invalid config was hit).
- `preprod/snapshots/tasks.py`: `"name"` → `"image_name"` (same fix as
#117550; identical change, no conflict whichever merges first).
## Known limitation
Only **literal** `extra={...}` dicts with constant string keys are
checked. Dynamic dicts (`extra=some_var`, `extra={**spread}`, computed
keys) can't be detected statically — but the literal case is the one
that actually bites.
## Test Plan
- [x] `test_S019` passes; full `tests/tools/test_flake8_plugin.py` suite
green (18 tests)
- [x] `flake8 --select=S019 src tests tools` reports clean after the two
fixes (was 2 hits before)
- [x] ruff + mypy clean on changed files1 parent 9fae755 commit a891ef8
3 files changed
Lines changed: 71 additions & 1 deletion
File tree
- src/sentry/hybridcloud/apigateway
- tests/tools
- tools
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
154 | | - | |
| 154 | + | |
155 | 155 | | |
156 | 156 | | |
157 | 157 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
393 | 393 | | |
394 | 394 | | |
395 | 395 | | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
58 | 95 | | |
59 | 96 | | |
60 | 97 | | |
| |||
300 | 337 | | |
301 | 338 | | |
302 | 339 | | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
303 | 353 | | |
304 | 354 | | |
305 | 355 | | |
| |||
0 commit comments