Skip to content

fix(rate-limit): return structured JSON for 429 responses - #6560

Open
acearth wants to merge 4 commits into
QuantumNous:mainfrom
acearth:agent/rate-limit-json-response
Open

fix(rate-limit): return structured JSON for 429 responses#6560
acearth wants to merge 4 commits into
QuantumNous:mainfrom
acearth:agent/rate-limit-json-response

Conversation

@acearth

@acearth acearth commented Jul 31, 2026

Copy link
Copy Markdown

📝 变更描述 / Description

通用限流中间件的 writeRateLimited 当前只返回 HTTP 429 和 Retry-After,响应体为空。浏览器/API 客户端若按 JSON 解析错误响应,会得到二次解析错误,无法向用户展示真正的限流原因。

本 PR 保留现有状态码和 Retry-After 行为,同时返回 dashboard API 已使用的稳定 JSON 结构:

{
  "success": false,
  "message": "Too many requests. Please try again later."
}

错误消息通过现有后端 i18n 机制支持英文、简体中文和繁体中文。该修复同时覆盖 Redis 与内存后端,以及共用 writeRateLimited 的 Global Web/API、Critical、Download、Upload 和 Search 限流。

This is intentionally separate from #6528: that PR fixes the model-specific in-memory limiter, while this PR fixes the shared IP/user limiter response used by CriticalRateLimit and the other generic rate-limit middleware.

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

$ go test ./middleware ./i18n -count=1
ok      github.com/QuantumNous/new-api/middleware
?       github.com/QuantumNous/new-api/i18n    [no test files]

$ go vet ./middleware ./i18n
# passed

$ git diff --check
# passed

回归测试验证:

  • 第三个 Redis 限流请求返回 HTTP 429;
  • 保留精确的 Retry-After
  • Content-Type 为 JSON;
  • 响应体包含 success: false 和可读、可本地化的 message

Summary by CodeRabbit

  • New Features

    • Rate-limit responses now return structured JSON with localized error messages.
    • Added English, Simplified Chinese, and Traditional Chinese translations for rate-limit errors.
    • The existing Retry-After header continues to provide retry guidance.
  • Bug Fixes

    • Improved clarity and consistency when request limits are exceeded.
    • Rate-limit messages now clearly advise trying again later.

@acearth
acearth marked this pull request as ready for review July 31, 2026 06:49
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The rate-limit middleware now returns localized JSON 429 responses. New i18n keys and translations support three locales. Tests cover response content, headers, critical limiter settings, and Redis namespace behavior.

Changes

Rate-limit localization

Layer / File(s) Summary
Localized rate-limit message contract
i18n/keys.go, i18n/locales/*.yaml
Adds MsgRateLimitExceeded and translations for English, Simplified Chinese, and Traditional Chinese.
JSON rate-limit response and validation
middleware/rate-limit.go, middleware/rate_limit_test.go
Returns a translated JSON 429 response while preserving Retry-After behavior. Tests verify response content, headers, limiter settings, and the CT Redis namespace.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CriticalRateLimit
  participant writeRateLimited
  participant i18n
  Client->>CriticalRateLimit: Send request
  CriticalRateLimit->>writeRateLimited: Reject exceeded request
  writeRateLimited->>i18n: Resolve MsgRateLimitExceeded
  i18n-->>writeRateLimited: Return localized message
  writeRateLimited-->>Client: Return JSON 429 and Retry-After
Loading

Possibly related PRs

Poem

A rabbit sees requests hop too fast,
So JSON 429 responses last.
Three locales make the message clear:
“Please try again later, dear.”
Retry-After guides each hurried hare.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: rate-limit middleware now returns structured JSON for HTTP 429 responses.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@middleware/rate_limit_test.go`:
- Around line 49-84: Add a separate deterministic test for CriticalRateLimit
with common.RedisEnabled disabled, reusing the router/request setup and
restoring the global setting afterward. Drive the in-memory limiter to its final
allowed request and assert the 429 response includes the configured Retry-After
header, application/json; charset=utf-8 content type, and the localized JSON
body. Keep the existing Redis test unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ed1e33e4-3271-488b-a614-121103b63f0e

📥 Commits

Reviewing files that changed from the base of the PR and between 8461e53 and b422ccb.

📒 Files selected for processing (6)
  • i18n/keys.go
  • i18n/locales/en.yaml
  • i18n/locales/zh-CN.yaml
  • i18n/locales/zh-TW.yaml
  • middleware/rate-limit.go
  • middleware/rate_limit_test.go

Comment thread middleware/rate_limit_test.go
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.

1 participant