Erros
Tabela completa de códigos de erro, classes e tratamento recomendado.
Princípios de tratamento
Seção intitulada “Princípios de tratamento”- Programático: use
instanceof(Web) ouwhen/switchpor tipo (Android/iOS) para tratamento específico - Código numérico: use
error.code(Web) ouerror.type(nativos) para tratamento granular - Serialização:
error.toJSON()(Web) retorna objeto sem stack trace — seguro para telemetria - Causa raiz:
error.cause(Web) ouerror.exception(Android) preserva o erro original
Web SDK — Códigos numéricos
Seção intitulada “Web SDK — Códigos numéricos”| 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 |
Código 8002 — reasons detalhados
Seção intitulada “Código 8002 — reasons detalhados”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 |
Tratamento Web SDK
Seção intitulada “Tratamento Web SDK”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()); }});Android SDK — Tipos de erro
Seção intitulada “Android SDK — Tipos de erro”ProvviErrorType (via ProvviResult)
Seção intitulada “ProvviErrorType (via ProvviResult)”| 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 |
Tratamento Android
Seção intitulada “Tratamento Android”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), ouUNKNOWNquando o motivo não vem como código; um motivo sem tipo próprio na tabela de tipos acima chega comoLICENSE_INVALID. Quando o próprio SDK recusa a configuração recebida, seguePOLICY_INVALID:com o campo recusado; numa falha local ao validar, segueVALIDATION_ERROR:com o tipo da falha.Lookup auth:,Session auth:ouBroker-v2 auth:— durante a captura, um serviço da Provvi recusou a chave. Depois deLookup auth:vemUNKNOWN: nessa recusa, o SDK não lê o código do motivo que o serviço manda. Depois deSession auth:e deBroker-v2 auth:vem o código que o serviço mandou, ouUNKNOWNquando 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.
iOS SDK — Erros de licença
Seção intitulada “iOS SDK — Erros de licença”| 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 |
Tratamento iOS
Seção intitulada “Tratamento iOS”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.")
// ...}API Backend — Erros HTTP
Seção intitulada “API Backend — Erros HTTP”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.
Licenciamento — Razões de rejeição
Seção intitulada “Licenciamento — Razões de rejeição”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 |