Códigos de exceção
Todo código que um serviço realmente retorna, agrupado por escopo e pelo que fazer a respeito.
O error.code é a metade estável e legível por máquina de uma falha. O texto da
mensagem muda com traduções e revisões de copy; o código não.
Os códigos têm escopo por serviço. Cada um abaixo está listado sob o serviço que o produz, e só aparecem aqui os que estão de fato em uso.
A mesma string pode existir em mais de uma origem. O rate_limit_exceeded do
gateway e o rate_limit_exceeded da autenticação são definições separadas que
por acaso concordam — case pelo código e pela chamada que você fez.
Do SDK
Produzidos localmente, sem ida ao servidor.
no_session401Uma chamada que precisa de sessão rodou sem nenhuma guardada.
request_timeout408O timeout que você configurou estourou.
network_error0Nada respondeu. É o caso de estar offline.
invalid_path400Um parâmetro de path era . ou ... Os ids são codificados na URL como um
único segmento, mas esses dois ainda levariam a outro endpoint, então a chamada é
recusada.
unknown_errorChegou uma resposta que não foi interpretada como erro.
Gateway
Toda chamada a um projeto passa antes pelo gateway em
https://<projeto>.nulvless.co. Ele confere a API key e o estado do projeto
antes de a requisição chegar a um serviço, então estes códigos podem voltar de
qualquer chamada do SDK.
project_unavailable403O projeto está num estado em que não pode atender requisições.
rate_limit_exceeded429Requisições demais vindas do seu IP. O cabeçalho Retry-After diz quando
tentar de novo. Um IP que insiste em rotas que não existem fica bloqueado por
dez minutos.
internal_error500O gateway falhou ao tratar a requisição.
service_not_enabled501O serviço não está instalado neste projeto, ou não neste ambiente.
bad_gateway502O serviço por trás do gateway não pôde ser alcançado.
service_unavailable503O serviço falhou ao ser configurado neste ambiente.
project_not_ready503O projeto ainda está sendo construído ou restaurado. Tente de novo em instantes.
upstream_timeout504O serviço demorou demais para começar a responder.
idle_timeout504O serviço parou de enviar dados no meio da resposta.
deadline_exceeded504A requisição passou do tempo total permitido para a rota.
project_paused540O projeto está pausado. Retome-o pelo dashboard.
Uma rota que o gateway não conhece responde 404 com corpo vazio, então não há
code para ler.
Autenticação
O maior escopo: cadastro, entrada, sessões, fatores, grants, OAuth.
Não autenticado — 401
unauthorized401Sem token de sessão válido.
invalid_credentials401A senha, código ou token não conferiu.
refresh_token_not_found401O refresh token não corresponde a nenhuma sessão. Autentique o usuário de novo.
refresh_token_already_used401O refresh token já tinha sido trocado e foi reenviado depois da janela de reuso. Por precaução, a sessão inteira é encerrada. Autentique o usuário de novo.
refresh_token_not_issued_here401O refresh token é mais novo do que a sessão conhece, então não foi emitido por este ambiente. Autentique o usuário de novo em vez de tentar outra vez.
Autenticado, mas barrado — 403
protected_action_denied403O modo sudo é exigido para esta ação.
mfa_required403O ambiente exige MFA e esta sessão nunca usou um segundo fator.
mfa_factors_limit_reached403O usuário já tem o máximo de apps autenticadores e fatores SMS que o ambiente permite. Remova um antes de adicionar outro.
mfa_phone_already_enrolled409Este telefone já é um dos fatores SMS do usuário.
mfa_phone_not_supported400phone foi enviado ao cadastrar um fator diferente de sms_otp.
registration_closed403O cadastro está desligado neste ambiente.
user_not_confirmed403A conta nunca foi confirmada.
user_banned403A conta está banida.
forbidden_resource_access403Sem grant no recurso, ou falta um escopo ou papel exigido.
forbidden_access_waiting_accept403Existe um grant, mas ainda como invited ou requested.
forbidden_special_role_required403A ação exige um papel específico.
cannot_leave_owner_access403Um dono não pode sair do próprio recurso.
oauth_account_link_required403A conta do provedor precisa ser vinculada a um usuário existente antes.
unavailable403O método está desabilitado neste ambiente.
action_verification_failed403 / 401Um desafio não pôde ser confirmado — código errado, ou tentativas demais.
not_allowed403 / 401 / 422Uma recusa genérica. Leia a mensagem.
Entrada rejeitada — 400
password_weak400Não passou nos requisitos de tamanho ou caracteres.
password_leaked400Encontrada em vazamento conhecido, e o ambiente bloqueia essas.
captcha_required400Um token de captcha era esperado e não veio.
captcha_verification_failed400O token de captcha foi rejeitado.
bad_oauth_state400O state do OAuth não conferiu.
bad_oauth_callback400O callback do provedor veio malformado.
redirect_uri_mismatch400A URI de redirecionamento não está na lista permitida.
provider_unavailable400O provedor social está desligado neste ambiente.
provider_unsupported_method400Aquele provedor não suporta o método pedido.
oauth_email_missing400O provedor não devolveu e-mail.
oauth_email_not_verified400O provedor devolveu um e-mail não verificado.
Conflito com dados existentes — 422
email_already_exists422Já em uso.
phone_already_exists422Já em uso.
username_already_exists422Já em uso.
user_missing_email422O ambiente exige e-mail e nenhum foi passado.
user_missing_phone422O ambiente exige telefone e nenhum foi passado.
user_already_confirmed422Confirmando algo já confirmado.
user_already_banned422Banindo alguém já banido.
user_not_banned422Desbanindo alguém que não está banido.
permission_already_granted422O grant já existe.
O cadastro pode devolver vários destes de uma vez — a message vira um array.
Agora não
rate_limit_exceeded429Tentativas demais. O corpo traz um retryAfter que o SDK não expõe.
Runtime das edge functions
Um escopo diferente da API da plataforma. Estes são produzidos pelo runtime que de fato executa a sua função, não pela API que faz o deploy — então o primeiro grupo você vê como resposta HTTP de uma invocação, e o segundo só nos logs.
Retornados por uma invocação
function_not_found404Nenhuma função naquele caminho.
function_unavailable403A função existe, mas o control plane se recusa a servi-la — desativada, ou o projeto dela não está servível. Um estado assentado, não transitório.
execution_timeout546Limite de tempo de parede excedido.
cpu_time_limit_exceeded546Limite de tempo de CPU excedido — a função estava ocupada, não esperando.
memory_limit_exceeded546Limite de memória excedido.
resource_unavailable503A função não pôde ser carregada — falha ao buscar metadados ou baixar o bundle. Vale repetir.
boot_failed503O worker não pôde ser iniciado. Vale repetir.
546 não é erro de digitação
As três violações de limite respondem com 546, um status fora do padrão
escolhido justamente para serem distinguíveis de qualquer coisa que o seu código
retorne. Case com ele diretamente — um status >= 500 genérico joga essas junto
com erros de servidor de verdade.
Quando o seu próprio código lança, o runtime responde um 500 puro, sem campo
code nenhum. Essa ausência é o sinal: falha com código veio da plataforma, 500
sem código veio da sua função.
Registrados nos logs
O runtime envia eventos para o serviço de logs, não para quem chamou. Quatro
carregam um error.code, e espelham as violações de limite acima — então um
546 que os seus usuários viram tem uma linha de log correspondente com o limite
que foi atingido:
internal_server_errorUm erro não tratado dentro da função.
memory_limit_exceededTraz runtime.memory_limit_mb.
execution_timeoutTraz runtime.timeout_ms.
cpu_time_limit_exceededTraz runtime.cpu_time_limit_ms.
Todo log do runtime também carrega um kind, que é como você os separa: log
para a saída do seu próprio console.*, boot para cold start (com
cold_start_ms), invoked para CPU e memória por requisição, shutdown para um
worker encerrando, e um por violação de limite.
Um shutdown carrega um reason. memory_limit_exceeded e
cpu_hard_limit_exceeded são logados como erro, cpu_soft_limit_reached como
aviso, e os rotineiros — inatividade, reciclagem por tempo de vida — como info.
Só kind: "log" é saída da sua função. Todo o resto é gerado pela plataforma e
marcado como interno, que é o que mantém a contabilidade do runtime fora das suas
métricas de consumo de log.
Notificações
Envio de e-mail e SMS, e os templates por trás disso.
unauthorized_platform401Chave errada ou ausente.
rate_limit_exceeded429A cota de envio deste canal acabou. Este não traz retryAfter.
O comms.email.send resolver sem erro significa que a mensagem foi aceita para
entrega, não entregue. Tudo depois desse ponto aparece no registro, não na
chamada.