Skip to main content
Toda resposta de erro da API Pontua usa o mesmo envelope JSON, independente da rota que falhou:
{
  "service": "NomeDoServico",
  "method": "nomeDoMetodo",
  "message": "Descrição legível do erro"
}
CampoSignificado
serviceClasse/serviço onde o erro foi originado
methodMétodo específico que falhou
messageMensagem em pt-BR pronta pra mostrar/logar
O status code HTTP identifica a categoria do erro. A mensagem é legível por humanos e tipicamente em português (pt-BR).

Status codes principais

StatusSignificadoRetry?
200 OKOperação concluída, body com dados
201 CreatedRecurso criado, body com ID gerado
204 No ContentOperação ok, sem body
400 Bad RequestValidação de schema falhou (campo errado, tipo errado)❌ Não — corrige o request
401 UnauthorizedToken ausente, inválido ou expirado❌ Não — corrige autenticação
403 ForbiddenAutenticado mas sem permissão❌ Não — verifica plano/escopo
404 Not FoundRecurso não existe (ID inválido ou de outro tenant)❌ Não — corrige ID
500 Internal Server ErrorErro inesperado no backend✅ Sim — backoff + retry
Outras categorias HTTP (4xx específicas como 409, 422 etc.) podem aparecer dependendo do endpoint. A message do envelope sempre indica a causa concreta.

Mensagens comuns

401 Unauthorized — falhas de autenticação

{
  "service": "AuthCoreGuard",
  "method": "canActivate",
  "message": "Token inválido"
}
MensagemCausa típica
Token inválidoMalformado, assinatura corrompida, ou de ambiente errado (PROD vs HML)
Token expiradoAtingiu o exp (expiração) — hora de rotacionar
→ Detalhes em Autenticação.

400 Bad Request — validação de schema

Vem do ValidationPipe global do NestJS. Indica que o payload tem problema estrutural (campo faltando, tipo errado, propriedade extra).
{
  "service": "ValidationPipe",
  "method": "transform",
  "message": [
    "nome should not be empty",
    "cpf must be a string"
  ]
}
A message pode ser um array de strings quando há múltiplos erros. Trate defensivamente:
const msg = Array.isArray(erro.message) ? erro.message.join('; ') : erro.message

404 Not Found — recurso inexistente

Atenção: se você está em multi-tenant, 404 pode significar “ID existe, mas em outra UN”. Cheque que o token pertence à UN do recurso.

500 Internal Server Error — erro interno

Indica algo inesperado no backend. Sempre transitório do ponto de vista do cliente:
  1. Retente com backoff (3-5 tentativas, jitter)
  2. Se persistir, abra chamado em tecnologia@pontua.com.br com:
    • service, method, message
    • Timestamp da primeira ocorrência (BRT)
    • Payload exato que estava sendo enviado

Estratégia de retry

const RETRIABLE_STATUSES = [500, 502, 503, 504]

async function comRetry(fn, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    try {
      return await fn()
    } catch (err) {
      const isRetriable = RETRIABLE_STATUSES.includes(err.status)
      const isLastAttempt = attempt === maxAttempts - 1

      if (!isRetriable || isLastAttempt) throw err

      // Exponential backoff: 1s, 2s, 4s, 8s, 16s + jitter
      const delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000
      await new Promise((r) => setTimeout(r, delay))
    }
  }
}

Error class wrapper (recomendado)

Encapsule o tratamento em uma classe específica para a Pontua:
class PontuaApiError extends Error {
  constructor(status, body) {
    const msg = Array.isArray(body.message) ? body.message.join('; ') : body.message
    super(`HTTP ${status} | ${body.service}.${body.method}: ${msg}`)
    this.name = 'PontuaApiError'
    this.status = status
    this.service = body.service
    this.method = body.method
    this.originalMessage = body.message
  }

  isRetriable() {
    return this.status >= 500
  }

  isAuthError() {
    return this.status === 401
  }
}

// Uso
try {
  await pontua.criarColaborador(dados)
} catch (e) {
  if (e instanceof PontuaApiError) {
    if (e.isAuthError()) await renovarToken()
    else if (e.isRetriable()) await comRetry(() => pontua.criarColaborador(dados))
    else throw e
  }
}

Logging recomendado

Capture sempre os 3 campos no seu observability stack:
if (!resp.ok) {
  const erro = await resp.json()
  log.error({
    status: resp.status,
    service: erro.service,
    method: erro.method,
    message: erro.message,
    url: resp.url,
    timestamp: new Date().toISOString(),
  })
}
Isso permite agregar erros por service.method no Datadog/Sentry/CloudWatch e identificar tendências.

Veja também