Skip to content

feat(functions): MitraApiError expõe retryAfterSeconds (#68) - #69

Merged
BrunoPinaFelipe merged 2 commits into
mainfrom
feat/68-retry-after
Oct 21, 2026
Merged

BrunoPinaFelipe merged 2 commits into
mainfrom
feat/68-retry-after

Conversation

@BrunoPinaFelipe

Copy link
Copy Markdown
Contributor

Closes #68

O que muda

MitraApiError ganha retryAfterSeconds, lido em createApiError: primeiro retry_after_seconds do corpo, depois o header Retry-After. É o que o Messenger devolve no 429 EMAIL_DAILY_QUOTA_EXCEEDED da cota diária de e-mail do app (mitralab-dev/mitra-messenger#173), no mesmo formato do RateLimitedException que ele já usa. O IAM e o mitra-common-ratelimit mandam só o header, por isso o fallback.

  • Só segundos inteiros. HTTP-date fica de fora: os serviços da Mitra mandam segundos, e uma data deixaria a espera dependente do relógio da Function.
  • Valor inválido no corpo cai para o header; inválido nos dois deixa o campo vazio.
  • retryable não muda (continua false no 429).
  • Versão 0.2.10-beta.0, no padrão dos PRs de feature do repo. O @mitralab.io/sdk-core continua 0.2.13.

Testes

Bloco "retry after" em src/http-client.test.ts, 10 casos: corpo vence header, header com espaços, corpo inválido usa header, e 7 casos que deixam o campo vazio. npm run check verde (141 testes).

Em aberto

O messenger.sendEmail() vem do @mitralab.io/sdk-core (mitralab-dev/mitra-core-sdk#90), que entra na linha 0.3.x com portão de rollout. O bump do core neste SDK fica para quando essa versão for publicada e liberada, ou para uma 0.2.14 com o método.

🤖 Generated with Claude Code

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@BrunoPinaFelipe
BrunoPinaFelipe requested a review from a team as a code owner October 20, 2026 19:33
Comment thread src/http-client.test.ts
@gandalf-the-grey-bot

Copy link
Copy Markdown

Gandalf, análise 1 · commit 3bc9f01

Pega-rápido

  • O PR expõe retryAfterSeconds em MitraApiError e interpreta o valor do corpo ou do header Retry-After, sem introduzir retry automático.
  • O problema é real: o transporte atual descartava o tempo indicado pelo servidor antes de entregá-lo ao consumidor.

Mérito

  • A solução é a menor alteração compatível: mantém a conversão centralizada em createApiError, usa a precedência body > header e ignora valores inválidos ou não seguros.
  • A necessidade está alinhada às issues do SDK e dos consumidores. Não há workaround razoável pela API pública atual.

Pilares

  • Qualidade: os casos de body, header, precedência e valores inválidos estão cobertos. Há uma melhoria menor pendente para proteger explicitamente retryable: false em 429.
  • Segurança: o campo é numérico e não altera credenciais, autorização ou dados de erro sensíveis.
  • Escalabilidade: o parser é constante, sem chamadas extras, estado ou retry automático. A política de uma tentativa por request permanece intacta.

Forma

  • retryAfterSeconds descreve claramente o contrato público, o helper mantém a precedência em um único ponto e o comentário explica a decisão de aceitar apenas segundos inteiros não negativos.

Score: 9,7/10
Confiança: alta para o código e o CI; o Sonar não foi verificável.

Padrões verificados

  • Contrato público exportado pelo SDK e compatível com MitraApiError existente.
  • Parsing de erro no transporte com fallback seguro do header.
  • Testes de transporte, declarações, exports, empacotamento e compatibilidade.
  • Versão 0.2.10-beta.0 alinhada entre package.json e package-lock.json, sem ativação de release por este PR aberto.

Sugestão para subir a nota

  • Como melhoria de cobertura, o smoke de consumidor poderia compilar uma leitura tipada de retryAfterSeconds nas declarações ESM e CommonJS. Isso é uma pergunta de cobertura, não um bloqueio deste PR.

Decisão: mergeável. A única ressalva é uma melhoria menor de teste, sem risco identificado para o merge ou para a política atual de retry.

Não consegui verificar o resultado do Sonar; ele não entrou na confiança nem no score.

Para uma nova análise depois de mudanças, comente /gandalf no PR ou me chame no Slack.

…e no 429 (#68)

Zero e valor acima do inteiro seguro no header, sem o trim que o Headers ja faz,
sem JSDoc no campo.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@BrunoPinaFelipe
BrunoPinaFelipe merged commit 44bf550 into main Oct 21, 2026
5 checks passed
@BrunoPinaFelipe
BrunoPinaFelipe deleted the feat/68-retry-after branch October 21, 2026 17:08
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.

MitraApiError expõe retryAfterSeconds no 429

2 participants