fix(rate-limiting): Honor span and feedback rate limits#3809
Conversation
The X-Sentry-Rate-Limits header parser did not recognize the `span` and `feedback` categories, so a rate limit for either was parsed as unknown and dropped. The SDK kept sending standalone spans and user feedback while those categories were rate limited. Map both header strings to their existing DataCategory values. The enum and client report serialization already handled them; only the parser was missing the cases. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. FeaturesDart
Fixes
Enhancements
DependenciesDeps
Internal Changes
🤖 This preview updates automatically when you update the PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3809 +/- ##
==========================================
+ Coverage 87.12% 87.22% +0.10%
==========================================
Files 336 336
Lines 12081 12083 +2
==========================================
+ Hits 10525 10540 +15
+ Misses 1556 1543 -13
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
There was a problem hiding this comment.
Pull request overview
Fixes rate-limit header parsing in the Sentry Dart SDK so X-Sentry-Rate-Limits entries for span and feedback correctly map to existing DataCategory values (instead of being treated as unknown and ignored), ensuring the SDK honors server-side throttling for these payload types.
Changes:
- Add
spanandfeedbackcases toRateLimitParser’s category string mapping. - Add regression tests covering parsing of
spanandfeedbackrate-limit categories.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/dart/lib/src/transport/rate_limit_parser.dart | Map span and feedback strings to their corresponding DataCategory values during rate-limit header parsing. |
| packages/dart/test/protocol/rate_limit_parser_test.dart | Add tests asserting span and feedback categories are parsed and applied with the expected duration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Android Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 1980dca | 354.77 ms | 346.96 ms | -7.82 ms |
| f3771ea | 379.02 ms | 363.91 ms | -15.11 ms |
| d3fb366 | 391.49 ms | 385.85 ms | -5.64 ms |
| bfabaf2 | 408.04 ms | 444.38 ms | 36.34 ms |
| eee3b3b | 373.20 ms | 372.54 ms | -0.65 ms |
| 393f8ec | 360.07 ms | 362.70 ms | 2.64 ms |
| e90cf93 | 374.35 ms | 368.40 ms | -5.95 ms |
| e04b24b | 504.72 ms | 516.43 ms | 11.71 ms |
| a5b28db | 383.85 ms | 387.65 ms | 3.80 ms |
| f42e9fb | 360.91 ms | 389.85 ms | 28.94 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 1980dca | 14.55 MiB | 15.87 MiB | 1.31 MiB |
| f3771ea | 14.31 MiB | 15.49 MiB | 1.19 MiB |
| d3fb366 | 13.93 MiB | 15.06 MiB | 1.13 MiB |
| bfabaf2 | 13.93 MiB | 15.06 MiB | 1.13 MiB |
| eee3b3b | 14.55 MiB | 15.87 MiB | 1.31 MiB |
| 393f8ec | 13.93 MiB | 15.06 MiB | 1.13 MiB |
| e90cf93 | 14.31 MiB | 15.56 MiB | 1.25 MiB |
| e04b24b | 13.93 MiB | 15.00 MiB | 1.06 MiB |
| a5b28db | 13.93 MiB | 15.18 MiB | 1.25 MiB |
| f42e9fb | 14.55 MiB | 15.87 MiB | 1.31 MiB |
iOS Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 32914d8 | 1275.47 ms | 1285.20 ms | 9.73 ms |
| eee3b3b | 1257.20 ms | 1255.59 ms | -1.62 ms |
| 793f4dc | 1262.50 ms | 1282.35 ms | 19.85 ms |
| 667e3c4 | 1254.70 ms | 1268.23 ms | 13.52 ms |
| f579250 | 1248.14 ms | 1250.15 ms | 2.01 ms |
| 2d65d04 | 1254.41 ms | 1269.24 ms | 14.84 ms |
| e0c8591 | 1259.85 ms | 1257.31 ms | -2.54 ms |
| 93b7728 | 1247.23 ms | 1264.87 ms | 17.64 ms |
| 640ad0c | 1241.04 ms | 1253.96 ms | 12.92 ms |
| d052aef | 1246.33 ms | 1253.04 ms | 6.71 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 32914d8 | 7.86 MiB | 9.44 MiB | 1.58 MiB |
| eee3b3b | 5.83 MiB | 6.28 MiB | 462.33 KiB |
| 793f4dc | 7.86 MiB | 9.44 MiB | 1.58 MiB |
| 667e3c4 | 5.83 MiB | 6.28 MiB | 459.83 KiB |
| f579250 | 5.66 MiB | 6.09 MiB | 448.36 KiB |
| 2d65d04 | 5.73 MiB | 6.17 MiB | 455.42 KiB |
| e0c8591 | 5.53 MiB | 5.96 MiB | 444.86 KiB |
| 93b7728 | 7.86 MiB | 9.44 MiB | 1.58 MiB |
| 640ad0c | 7.86 MiB | 9.44 MiB | 1.58 MiB |
| d052aef | 5.73 MiB | 6.17 MiB | 453.76 KiB |
The
X-Sentry-Rate-Limitsheader parser did not recognize thespanandfeedbackcategories. A rate limit for either was parsed asunknownand discarded by the parser, so the SDK kept sending standalone spans and user feedback while the server had rate limited those categories — risking more important data being dropped downstream once the backoff escalated.The fix maps both header strings to their existing
DataCategoryvalues.DataCategory.span/DataCategory.feedbackand the client-report serialization already handled these categories; onlyRateLimitParser._fromStringValuewas missing the cases, so the three category lists had drifted apart.Regression coverage added in
rate_limit_parser_test.dartfor both categories (mirroring the existingtrace_metric/log_bytecases).Closes #3787