Pular para o conteúdo

Erros

Tabela completa de códigos de erro, classes e tratamento recomendado.

  1. Programático: use instanceof (Web) ou when/switch por tipo (Android/iOS) para tratamento específico
  2. Código numérico: use error.code (Web) ou error.type (nativos) para tratamento granular
  3. Serialização: error.toJSON() (Web) retorna objeto sem stack trace — seguro para telemetria
  4. Causa raiz: error.cause (Web) ou error.exception (Android) preserva o erro original

Código Constante Classe Quando ocorre
1000 UNKNOWN ProvviError Erro genérico não classificado
2002 BROWSER_NOT_SUPPORTED ProvviBrowserError Browser não suportado — exige Safari ou Chrome no celular
3001 STREAM_OPEN_FAILED ProvviStreamError Falha ao abrir câmera (permissão negada, câmera em uso)
3002 STREAM_CAPTURE_FAILED ProvviStreamError Falha ao capturar frame (canvas, encoding JPEG)
4001 SESSION_FETCH_FAILED ProvviAPIError Sessão não encontrada, expirada ou já capturada
4002 INGEST_FAILED ProvviAPIError Erro no envio da captura (rejeição do servidor)
5001 CAPTURE_FAILED ProvviCaptureError Erro na orquestração do pipeline
5002 TOKEN_REQUIRED ProvviCaptureError open() chamado sem token
6001 GPS_UNAVAILABLE ProvviGeolocationError API de geolocalização não disponível
6002 GPS_DENIED ProvviGeolocationError Usuário negou permissão de localização
6003 GPS_TIMEOUT ProvviGeolocationError Timeout na aquisição de GPS
7001 UPLOAD_FAILED ProvviUploadError Falha no upload da captura
8001 LICENSE_KEY_MISSING ProvviLicenseError licenseKey não informada
8002 LICENSE_INVALID ProvviLicenseError Licença rejeitada — código genérico, ver details.reason abaixo
8003 LICENSE_NETWORK_ERROR ProvviLicenseError Falha de rede na validação

O código LICENSE_INVALID (8002) cobre múltiplas situações. O motivo específico é acessível via error.details.reason (Web) ou pelo campo reason na resposta de /validate:

details.reason Situação
INVALID_KEY Chave não encontrada no banco, ou chave antiga depois de uma rotação
REVOKED Licença desativada pelo administrador
EXPIRED Contrato expirado
VOLUME_EXCEEDED Limite mensal de capturas atingido
CLIENT_SUSPENDED Conta do cliente suspensa
import { EVENTS, ProvviLicenseError, ProvviStreamError, CODES } from 'provvi-camera.es.js';
camera.addEventListener(EVENTS.ERROR, (e) => {
const err = e.detail.error;
// Por classe
if (err instanceof ProvviLicenseError) {
// err.details.reason → INVALID_KEY, REVOKED, EXPIRED, etc.
showLicenseError(err.details.reason);
return;
}
if (err instanceof ProvviStreamError) {
showCameraError(err.message);
return;
}
// Por código numérico
switch (err.code) {
case CODES.TOKEN_REQUIRED:
console.error('Token não fornecido');
break;
case CODES.GPS_DENIED:
showGpsWarning();
break;
default:
reportToSentry(err.toJSON());
}
});

Tipo Descrição Recuperável
Permissões
PERMISSION_DENIED Câmera ou localização negada Sim — solicitar novamente
Integridade
DEVICE_COMPROMISED Aparelho recusado pela atestação da captura: bootloader destravado, sistema não verificado, ou chave de atestação revogada ou suspensa pelo Google (emulador e aparelho sem atestação de hardware falham antes, no provisionamento) Não pelo app; a suspensão o Google pode levantar, e aí o aparelho volta a capturar sozinho
STRONGBOX_UNAVAILABLE StrongBox ausente (não bloqueante) N/A
ATTESTATION_ERROR Sem uso: o SDK não devolve este tipo desde a 8d, que tirou o Play Integrity do aparelho N/A
Câmera
CAMERA_NOT_FOUND Sem câmera física Não
CAMERA_IN_USE Câmera em uso por outro app Sim — fechar outro app
CAMERA_TIMEOUT Sem frame em 10 segundos Sim — retry
CAMERA_ERROR Erro genérico de câmera Sim — retry
Localização
MOCK_LOCATION_DETECTED GPS falso detectado Não
LOCATION_UNAVAILABLE Nenhuma fonte de localização respondeu, com a permissão concedida; a captura não é assinada Sim — ativar a localização e capturar de novo
Recaptura
RECAPTURE_SUSPECTED Foto de tela detectada Não
Assinatura
SIGNING_FAILED Falha C2PA (c2pa-rs) Sim — retry
MANIFEST_INVALID Manifesto corrompido Sim — retry
FRAME_HASH_FAILED Falha SHA-256 Sim — retry
Rede
NETWORK_UNAVAILABLE Sem conectividade Sim — verificar rede
BACKEND_UNAVAILABLE Upload falhou Sim — retry via retryUpload()
BACKEND_AUTH_FAILED API Key inválida (401) Verificar credenciais
BACKEND_TIMEOUT Timeout no upload Sim — retry
TSA_UNAVAILABLE Timestamp Authority offline Sim — retry automático
Relógio e frame
CLOCK_SUSPICIOUS Reservado para desvio de relógio acusado pelo servidor; o SDK não o produz hoje (o servidor recusa desvio acima de 300 s por outro motivo) Não
STALE_FRAME O frame foi aceito há mais de 300 s quando a captura chegou ao portão; não é assinado Sim — capturar de novo
Licenciamento
LICENSE_KEY_MISSING licenseKey vazio no config Configurar a chave
LICENSE_NOT_VALIDATED validateLicense() não chamado Chamar antes de capture()
LICENSE_INVALID Licença recusada sem um tipo mais específico nesta tabela: chave não reconhecida (inclusive a chave antiga, depois de uma rotação), recusa por um motivo sem tipo próprio, licença com configuração que o SDK recusa, falha local do SDK ou do aparelho ao validar, ou recusa da chave por um serviço da Provvi durante a captura Verificar no Admin Console; persistindo, contatar Provvi
LICENSE_REVOKED Licença revogada Contatar Provvi
LICENSE_EXPIRED Contrato expirado Renovar contrato
LICENSE_VOLUME_EXCEEDED Limite mensal atingido Ampliar volume
LICENSE_NETWORK_ERROR Falha de comunicação com o servidor de licenças, detectada pelo SDK, sem validação recente para tolerar Verificar conexão
LICENSE_VALIDATION_UNAVAILABLE O servidor de licenças respondeu sem veredito (erro HTTP, ou resposta de sucesso sem o veredito valid); não há tolerância com o último resultado guardado Sim — tentar de novo mais tarde
LICENSE_POLICY_CHANGED_DURING_CAPTURE A política da licença mudou enquanto a captura estava em curso Sim — repetir a captura
LICENSE_CLIENT_SUSPENDED Conta suspensa Contatar Provvi
Genérico
UNKNOWN Erro não classificado Depende
when (outcome) {
is CaptureOutcome.LicenseError -> {
// error.message é texto técnico: vai para o log, não para a tela.
logLicenseError(outcome.error.type, outcome.error.message)
when (outcome.error.type) {
ProvviErrorType.LICENSE_EXPIRED -> showRenewDialog()
ProvviErrorType.LICENSE_VOLUME_EXCEEDED -> showUpgradeDialog()
ProvviErrorType.LICENSE_REVOKED -> blockCapture()
ProvviErrorType.LICENSE_POLICY_CHANGED_DURING_CAPTURE -> retryCapture()
ProvviErrorType.LICENSE_VALIDATION_UNAVAILABLE -> showRetryLater()
// Mensagem do app, por exemplo: "Sem conexão. Verifique a internet e tente de novo."
ProvviErrorType.LICENSE_NETWORK_ERROR -> showNoConnection()
// Mensagem do app, por exemplo: "Não foi possível validar a licença. Contate o suporte."
else -> showLicenseProblem()
}
}
is CaptureOutcome.BackendError -> {
when (outcome.errorType) {
BackendErrorType.TSA_UNAVAILABLE -> scheduleRetry(outcome.result)
BackendErrorType.AUTH_FAILED -> checkCredentials()
else -> showRetryDialog(outcome.message)
}
}
// ...
}

Decida o tratamento por error.type. A error.message é texto técnico, para log e suporte: não a mostre ao usuário final e não decida por ela. Nos tipos de licença, ela começa assim:

Tipo Começo da error.message
LICENSE_KEY_MISSING licenseKey não configurado em ProvviConfig
LICENSE_NOT_VALIDATED Chame validateLicense() antes de, seguido do método chamado; ou ProvviSDK.configure() not called
LICENSE_INVALID Licença inválida:; ou Lookup auth:, Session auth: ou Broker-v2 auth: (abaixo)
LICENSE_REVOKED, LICENSE_EXPIRED, LICENSE_VOLUME_EXCEEDED, LICENSE_CLIENT_SUSPENDED Licença inválida:, seguido do código do motivo (REVOKED, EXPIRED, VOLUME_EXCEEDED ou CLIENT_SUSPENDED)
LICENSE_NETWORK_ERROR Falha de comunicação com o servidor de licenças:, seguido do tipo da falha (por exemplo, UnknownHostException) ou de tolerância sem rede esgotada, sem código de motivo
LICENSE_VALIDATION_UNAVAILABLE Validação de licença indisponível:
LICENSE_POLICY_CHANGED_DURING_CAPTURE A política da licença mudou durante a captura

Em LICENSE_INVALID:

  • Licença inválida: — a validação da licença não a aceitou. Numa recusa pelo servidor de licenças, segue o código do motivo (por exemplo, INVALID_KEY), ou UNKNOWN quando o motivo não vem como código; um motivo sem tipo próprio na tabela de tipos acima chega como LICENSE_INVALID. Quando o próprio SDK recusa a configuração recebida, segue POLICY_INVALID: com o campo recusado; numa falha local ao validar, segue VALIDATION_ERROR: com o tipo da falha.
  • Lookup auth:, Session auth: ou Broker-v2 auth: — durante a captura, um serviço da Provvi recusou a chave. Depois de Lookup auth: vem UNKNOWN: nessa recusa, o SDK não lê o código do motivo que o serviço manda. Depois de Session auth: e de Broker-v2 auth: vem o código que o serviço mandou, ou UNKNOWN quando o que veio não é um código. O tipo é LICENSE_INVALID, e não o tipo específico da tabela: uma chave revogada, expirada ou rotacionada pode chegar assim.

Caso Enum Descrição
Chave vazia .keyMissing licenseKey não configurado
Chave inválida .invalidKey("INVALID_KEY") Não encontrada no backend, ou chave antiga depois de uma rotação
Revogada .invalidKey("REVOKED") Desativada pelo admin
Expirada .invalidKey("EXPIRED") Contrato vencido
Volume excedido .invalidKey("VOLUME_EXCEEDED") Limite mensal
Conta suspensa .invalidKey("CLIENT_SUSPENDED") Cliente suspenso
Rede .networkError(error) Falha de rede + sem cache válido
switch outcome {
case .licenseError(let reason):
switch reason {
case "EXPIRED": showRenewDialog()
case "VOLUME_EXCEEDED": showUpgradeDialog()
case "REVOKED", "CLIENT_SUSPENDED": blockCapture()
default: showAlert("Licença: \(reason)")
}
case .backendError(let message, let session):
if let session = session {
// Captura local OK — agendar retry
scheduleRetry(session)
}
case .deviceCompromised:
showAlert("Dispositivo comprometido. Captura bloqueada.")
// ...
}

Os erros HTTP da captura web (create, sessão, ingest) — com corpos e ações — estão documentados em Erros e bloqueios da Integração Web.


Quando /validate retorna { "valid": false, "reason": "..." }:

Reason Descrição Ação recomendada
INVALID_KEY Chave não encontrada no banco, ou chave antiga depois de uma rotação Verificar chave no Admin Console
REVOKED Licença desativada pelo admin Contatar Provvi
EXPIRED Data de expiração do contrato ultrapassada Renovar contrato
VOLUME_EXCEEDED Capturas excederam o limite mensal Aguardar reset ou ampliar volume
CLIENT_SUSPENDED Conta do cliente suspensa Contatar Provvi