Pular para o conteúdo
Última atualização

Tratamento de Erros

A API Dinie usa o formato RFC 9457 Problem Details para todas as respostas de erro. Todo erro tem uma estrutura consistente, uma URI de tipo legível por máquina e uma descrição legível por humanos.

Formato da Resposta de Erro

Todos os erros são retornados com content type application/problem+json:

{
  "type": "https://api.dinie.com.br/errors/invalid-request",
  "title": "Invalid Request",
  "status": 400,
  "detail": "The 'cpf' field is required.",
  "instance": "/v3/customers"
}

Campos Principais

CampoTipoDescrição
typestring (URI)URI que identifica o tipo de erro. Resolve para a documentação.
titlestringResumo curto do tipo de problema. Consistente em todas as ocorrências.
statusintegerCódigo de status HTTP desta ocorrência.
detailstringExplicação legível específica desta ocorrência.
instancestring (URI)URI que identifica esta ocorrência específica (geralmente o path da requisição).

Campos de Extensão

CampoTipoDescrição
codestringSub-tipo legível por máquina (ex.: missing_required_field, invalid_cpf)
paramstringO parâmetro da requisição que causou o erro
errorsarrayLista de erros individuais por campo (para falhas de validação)

Tip: Use o campo code para tratamento programático de erros. O type identifica a categoria ampla, enquanto o code aponta o problema específico.

Erros de Validação de Campos

Quando uma requisição tem sintaxe correta mas valores de campo inválidos, a resposta inclui um array errors com detalhes de cada campo inválido:

{
  "type": "https://api.dinie.com.br/errors/validation-failed",
  "title": "Validation Failed",
  "status": 422,
  "detail": "One or more fields failed validation.",
  "errors": [
    {
      "param": "email",
      "detail": "Must be a valid email address.",
      "code": "invalid_format"
    },
    {
      "param": "cpf",
      "detail": "CPF is already registered.",
      "code": "already_exists"
    }
  ]
}

Cada item no array errors contém:

CampoDescrição
paramO nome do campo que falhou na validação
detailExplicação legível da falha de validação
codeCódigo de erro de validação legível por máquina

Referência de Tipos de Erro

StatusTipoTítuloQuando
400invalid-requestInvalid RequestSintaxe malformada, content type ausente ou parâmetros inválidos
401authentication-failedAuthentication FailedCredenciais ou token ausentes ou inválidos
403forbiddenForbiddenToken válido mas permissões insuficientes
404not-foundNot FoundRecurso não existe ou não está acessível para este parceiro
409conflictConflictRecurso já existe ou ação conflita com o estado atual
422validation-failedValidation FailedRequisição parseada com sucesso mas valores dos campos são inválidos
429rate-limit-exceededRate Limit ExceededMuitas requisições. Verifique o header Retry-After.
500internalInternal ErrorErro inesperado no servidor

Todas as URIs de tipo são prefixadas com https://api.dinie.com.br. Clique no tipo para ver causas comuns, exemplos e resolução.

Tratamento de Erros nos SDKs

Os SDKs lançam exceções tipadas para cada categoria de erro:

import Dinie, {
  AuthenticationError,
  NotFoundError,
  ValidationError,
  RateLimitError,
} from "dinie";

try {
  const customer = await dinie.customers.create({
    cpf: "invalid",
    name: "Joao Silva",
    email: "joao@example.com",
  });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error("Falha na validação:", error.message);
    for (const fieldError of error.errors) {
      console.error(`  ${fieldError.param}: ${fieldError.detail}`);
    }
  } else if (error instanceof AuthenticationError) {
    console.error("Falha na autenticação -- verifique as credenciais");
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limit atingido. Tente novamente em ${error.retryAfter}s`);
  } else if (error instanceof NotFoundError) {
    console.error("Recurso não encontrado");
  }
}

Rate Limiting

Todas as respostas incluem headers de rate limit:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1709478060

Quando limitado por rate (429), o header Retry-After indica quantos segundos esperar:

Retry-After: 30

Estratégia de Retry

Nem todos os erros devem ser reenviados. Use esta tabela para decidir:

StatusReenviar?Estratégia
400NãoCorrija a requisição. O payload está malformado.
401Uma vezRenove o access token e reenvie.
403NãoVerifique as permissões com seu gerente de conta.
404NãoO recurso não existe.
409NãoResolva o conflito (ex.: recurso duplicado).
422NãoCorrija os valores dos campos inválidos.
429SimAguarde o tempo indicado em Retry-After e reenvie.
500SimReenvie com exponential backoff.

Exponential Backoff

Para erros que podem ser reenviados (429, 500), use exponential backoff com jitter:

const MAX_RETRIES = 3;

async function requestWithRetry(fn: () => Promise<any>) {
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (!isRetryable(error) || attempt === MAX_RETRIES) throw error;

      const baseDelay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
      const jitter = Math.random() * 500;
      await sleep(baseDelay + jitter);
    }
  }
}

Info: Os SDKs implementam retries automáticos com exponential backoff para respostas 429 e 500. Você pode configurar o número máximo de retries ao inicializar o client.