Skip to content

Themia 0.5.4 — RateLimitException → 429 + Retry-After (coord #0001)#107

Merged
klomkling merged 2 commits into
mainfrom
feat/aspnetcore-ratelimit
Jun 17, 2026
Merged

Themia 0.5.4 — RateLimitException → 429 + Retry-After (coord #0001)#107
klomkling merged 2 commits into
mainfrom
feat/aspnetcore-ratelimit

Conversation

@klomkling

Copy link
Copy Markdown
Owner

Unblocks ezy-assets Phase-1 middleware swap.

What

  • New Themia.AspNetCore.Exceptions.RateLimitException(message, int retryAfterSeconds, errorCode?, metadata?).
  • ProblemDetailsMiddleware maps it to HTTP 429 + Retry-After header + retryAfterSeconds problem extension.
  • RetryAfterSeconds is a domain value → exception stays HTTP-agnostic (middleware owns the type→status map), consistent with the existing typed exceptions.

Why

ezy-assets returns 429 + Retry-After on OTP-resend cooldown; 0.5.3 middleware mapped every ValidationException → 400, regressing those endpoints. coord #1.

Not doing

FluentValidation/ArgumentException → 400 mapping — would couple Themia.AspNetCore to FluentValidation. Consumers throw Themia ValidationException instead.

Test plan

ProblemDetailsMiddlewareTests: 429 + Retry-After: 30 header + retryAfterSeconds: 30 + errorCode. 24/24 net8+net10 green; full solution 0/0.

…rSeconds (coord #1)

ProblemDetailsMiddleware maps RateLimitException to HTTP 429, emits the Retry-After header and a
retryAfterSeconds problem extension. retryAfterSeconds is a domain value, so the exception stays
HTTP-agnostic (middleware owns the type->status map). Unblocks the ezy-assets Phase-1 middleware
swap (OTP-resend cooldown). Version 0.5.4.
@klomkling klomkling merged commit d6f835a into main Jun 17, 2026
3 checks passed
@klomkling klomkling deleted the feat/aspnetcore-ratelimit branch June 17, 2026 22:42
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