Documentação
Solução de problemasTratamento de errosTratando erros

Tratando erros

Quais falhas o seu código repete, quais precisam do usuário, e quais são suas para corrigir.

Toda falha chega no mesmo formato, então a pergunta interessante não é como ler uma — a referência cobre isso — mas o que fazer com ela.

Só existem quatro respostas, e o status_code diz qual se aplica antes de você sequer olhar o code.

Ramifique primeiro pelo status

400, 413, 422Bug seu

A requisição estava malformada ou os dados foram rejeitados. Repetir não muda nada.

401Entrar de novo

Sem sessão válida. Mande para a tela de entrada, não para uma tela de erro.

403Pedir algo ao usuário

Autenticado, mas falta uma permissão, uma confirmação ou um segundo fator.

429, 503Esperar e repetir

Não há nada errado com a requisição. Recue.

Só então o code importa — ele diz qual dessas, para você escrever uma mensagem útil em vez de "algo deu errado".

const { data, error } = await nulvless.auth.signIn({ email, password });

if (error) {
  if (error.status_code === 401) return goToSignIn();
  if (error.status_code === 429) return backOff(error);

  return showMessage(messageFor(error.code) ?? error.message);
}

A família 403 é a interessante

Um 403 quase nunca significa "desista". Significa que o usuário pode fazer algo a respeito, e o code diz o quê:

protected_action_deniedConfirmar identidade

Modo sudo é exigido. Inicie o fluxo de sudo e repita.

mfa_requiredCadastrar um fator

O ambiente exige MFA e esta sessão nunca usou um.

user_not_confirmedConcluir o cadastro

O endereço ou telefone nunca foi confirmado.

forbidden_access_waiting_acceptAceitar o convite

Existe um grant, mas ainda pendente — está na caixa de entrada da pessoa.

forbidden_resource_accessRealmente não permitido

Sem grant no recurso, ou falta um escopo ou papel.

Juntar todos numa única tela de "Acesso negado" é o erro mais comum, e deixa travada gente que estava a um clique de continuar.

Deixe os eventos cuidarem do sudo

O protected_action_denied é comum o bastante para o SDK emitir um evento, então você não precisa capturá-lo em cada ponto de chamada:

nulvless.auth.on('sudo-required', async () => {
  await nulvless.auth.sessions.sudo();
  openSudoPrompt();
});

Existe também um evento unauthorized para o caso do 401. Veja Events.

Recuando

Dois códigos significam "agora não":

if (error.code === 'rate_limit_exceeded' || error.code === 'service_overloaded') {
  await wait(backoff());
}

O SDK não expõe o Retry-After

O NulvlessError carrega exatamente três campos — code, message e status_code. O serviço de auth até coloca um retryAfter no corpo da resposta de limite, e o service_overloaded vem com um header Retry-After, mas nenhum dos dois sobrevive até o objeto de erro. Use o seu próprio backoff, ou leia a resposta crua se precisar da dica.

Nunca repita um 400, 413 ou 422. A requisição vai falhar igual toda vez.

Erros de validação chegam em lista

message é string | string[] — um array quando vários campos falharam de uma vez. Achate isso num lugar só:

const text = Array.isArray(error.message) ? error.message.join(', ') : error.message;

O cadastro é onde você encontra isso primeiro: uma requisição pode ser rejeitada pelo e-mail e pelo telefone na mesma resposta.

Mostre o código quando não souber explicar

Para o que você não escreveu mensagem, mostrar o code cru é melhor que um pedido de desculpas genérico — é o que o seu time de suporte vai pedir, e é estável entre versões de um jeito que o texto da mensagem não é.

A plataforma anexa um reference a uma falha de deploy não classificada (internal_error) para o suporte achar a linha de log. Como o retryAfter, ele está no corpo da resposta e não no NulvlessError, então recorra à resposta crua se quiser exibi-lo.

Alguns erros nunca chegam à rede

Alguns códigos são produzidos pelo próprio SDK, antes ou no lugar de uma requisição. Têm o mesmo formato, então a mesma ramificação atende:

no_session401

Uma chamada que precisa de sessão rodou sem nenhuma guardada.

request_timeout408

O timeout que você configurou estourou.

network_error0

A requisição nunca completou. status_code é 0 — nada respondeu.

unknown_error

Chegou uma resposta que não foi interpretada como payload de erro.

status_code: 0 é o teste confiável para "offline ou inalcançável", e merece mensagem própria.

Edge functions respondem 546

Se você chama uma edge function do seu próprio código, três falhas chegam com status 546, não com um 5xx que você reconheceria:

if (response.status === 546) {
  const { code } = await response.json();
  // execution_timeout | cpu_time_limit_exceeded | memory_limit_exceeded
}

É deliberadamente fora da faixa padrão, para uma violação de limite nunca ser confundida com erro de servidor. Um 500 puro, sem code no corpo significa o oposto — a sua função lançou, e a plataforma não está afirmando saber por quê.

Os códigos têm escopo por serviço

A mesma string pode estar definida em mais de um serviço, e o código que você vê depende de quem respondeu. O unauthorized do serviço de auth e o unauthorized da API da plataforma querem dizer a mesma coisa em espírito, mas são definições separadas.

A página de Códigos de exceção lista por escopo, e só os que estão de fato em uso.

Próximos

Nesta página