Pular para o conteúdo
getnextpdf.com

Erros de runtime e suporte

Estas entradas documentam as exceções geradas pela camada de suporte de runtime: a política de degradação, o transporte HTTP baseado em cURL, o circuit breaker de resiliência, o emissor de Security Information and Event Management (SIEM), o render manifest, a inspeção de PDF e o subsistema de chaos engineering.

Toda exceção do NextPDF estende NextPdfException, que implementa ContextAwareExceptionInterface e expõe getContext(): array para logging de diagnóstico estruturado. Uma subclasse preenche esse array somente quando sobrescreve getContext(); a base retorna um array vazio. Três exceções nesta página (DegradedException, CircuitBreakerOpenException e InspectException) estendem a RuntimeException do PHP diretamente e expõem seus dados por meio de propriedades públicas readonly em vez de getContext(). Cada entrada abaixo nomeia as propriedades ou chaves de contexto exatas que a classe carrega, retiradas da origem.

  • Gerada quando. O pipeline de renderização encontra uma capacidade degradada que viola a política de degradação ativa. Sob DegradationPolicy::Strict, qualquer degradação de alto impacto (ComplianceRisk, SemanticLoss ou Blocking) a gera; sob DegradationPolicy::Balanced, apenas um impacto Blocking a gera.
  • Classe. Estende RuntimeException diretamente (não NextPdfException), então não carrega getContext().
  • Dados carregados. Duas propriedades públicas readonly: $capability (o objeto de valor Capability que disparou a rejeição, incluindo seu id, status, reason, fallbackTarget e impact) e $policy (a DegradationPolicy ativa no momento da rejeição). A mensagem tem a forma Feature "<id>" is <status>: <reason> (policy: <policy>).
  • Recuperação. Inspecione $capability para identificar o recurso ausente e sua causa. Instale o componente que a capacidade exige, aceite uma configuração de menor impacto, ou relaxe a política de Strict para Balanced quando a degradação for aceitável para o caso de uso. Chame $capability->isAvailable() / isDegraded() para orientar mensagens voltadas ao usuário.

Estas três exceções se originam no cliente PSR-18 baseado em cURL e em seu decorator com consciência de segurança. As duas primeiras estendem NextPdfException, mas não sobrescrevem getContext(), então seu getContext() retorna um array vazio; os dados de diagnóstico são alcançados pelo acessor getRequest() do PSR-18 e pelo throwable anterior encadeado.

  • Gerada quando. A requisição HTTP não pode ser concluída por causa de uma falha de nível de rede: falha de resolução do Domain Name System (DNS), timeout de conexão ou erro de handshake do Transport Layer Security (TLS). Ela também é a classe que o decorator com consciência de segurança gera para uma rejeição de segurança (recusa de Server-Side Request Forgery, recusa de DNS-rebinding ou um redirecionamento negado).
  • Classe. Implementa o PSR-18 Psr\Http\Client\NetworkExceptionInterface.
  • Dados carregados. getRequest() retorna o RequestInterface que falhou. O erro de transporte de origem, quando presente, é o throwable anterior encadeado. getContext() retorna um array vazio (o padrão base).
  • Recuperação. Uma falha de rede pode ser transitória — tente novamente com backoff se a requisição for idempotente. Uma rejeição de segurança não é transitória e deve falhar de forma fechada: não tente novamente; corrija a URL de destino ou a política de SSRF. Leia a mensagem e o throwable anterior para distinguir as duas.
  • Gerada quando. A requisição em si não pode ser enviada porque está malformada, por exemplo uma URL inválida ou uma requisição que falhou na validação de SSRF antes de qualquer chamada de rede.
  • Classe. Implementa o PSR-18 Psr\Http\Client\RequestExceptionInterface.
  • Dados carregados. getRequest() retorna o RequestInterface problemático; a causa subjacente, quando presente, é o throwable anterior encadeado. getContext() retorna um array vazio.
  • Recuperação. Este é um defeito de entrada do chamador ou de política, não uma falha transitória. Não tente novamente sem alterações. Corrija a URL, os headers ou o body da requisição, ou ajuste a allowlist de SSRF se o destino for legitimamente permitido, então reenvie a requisição.
  • Gerada quando. Internamente, dentro de SecurityAwareHttpClient, para marcar uma falha de transporte interno genuinamente transitória (DNS, conexão ou timeout gerada pelo cliente PSR-18 interno) como elegível para o orçamento de retry delimitado. É a única classe elegível para retry que o loop de retry do decorator reconhece; uma exceção não encapsulada (uma rejeição de segurança gerada pelo decorator) é tratada como fatal.
  • Classe. Implementa o PSR-18 Psr\Http\Client\NetworkExceptionInterface. Marcada como @internal — ela é criada e desencapsulada inteiramente dentro de SecurityAwareHttpClient e nunca escapa do decorator.
  • Dados carregados. getRequest() retorna a requisição que falhou. A ClientExceptionInterface de transporte interno original é preservada como o throwable anterior encadeado (getPrevious()) e re-exposta de forma idêntica ao chamador assim que o orçamento de retry se esgota, para que o contrato público do PSR-18 fique inalterado. getContext() retorna um array vazio.
  • Recuperação. O código de aplicação não captura este tipo diretamente. Capture a exceção interna re-exposta que o decorator retorna após o orçamento de retry ser gasto, e trate falhas transitórias repetidas como um problema de disponibilidade upstream.
  • Gerada quando. Um CircuitBreaker no estado CircuitBreakerState::Open rejeita uma chamada de forma fail-fast, antes de qualquer invocação downstream. Existe para permitir que os chamadores distingam “o serviço remoto está inacessível agora” (uma falha de transporte transitória, que vale a pena degradar) de “o pool de conexões teria sido esgotado por esta chamada” (fail-fast, nenhuma rede tentada) — a mitigação de negação de serviço em lote exigida para clientes de Public Key Infrastructure (PKI).
  • Classe. Estende RuntimeException diretamente, então não carrega getContext().
  • Dados carregados. Duas propriedades públicas readonly: $breakerName (o identificador do breaker aberto) e $secondsUntilHalfOpen (o cooldown aproximado restante antes que o breaker faça a transição para half-open). A mensagem tem a forma Circuit breaker "<name>" is OPEN (cooldown ~<n>s remaining); call rejected fail-fast.
  • Recuperação. Não martele o breaker — aguarde pelo menos $secondsUntilHalfOpen antes de tentar novamente, ou degrade a operação. Nenhuma chamada de rede foi tentada, então isto não é evidência de que o serviço remoto em si falhou; é back-pressure protegendo o pool de conexões.
  • Gerada quando. Um emissor de eventos SIEM não consegue persistir ou encadear um registro. Ela expõe falhas de nível de sistema de arquivos (open, lock, seek, write, fflush, read) e falhas de integridade de hash-chain (chain: índice fora de ordem, registro de cauda malformado ou deriva de round-trip JSON) compartilhadas pelo log de eventos de hash-chain e pelos adaptadores de emissor de arquivo JSON-lines.
  • Classe. Estende NextPdfException e sobrescreve getContext().
  • Chaves de contexto. operation (um de open, lock, seek, write, fflush, read, chain), path (o caminho de log de destino) e detail (um detalhe legível por humanos, como contagens de bytes ou índice esperado versus real). Estes também são alcançáveis por meio de getOperation(), getPath() e getDetail(). A mensagem tem a forma SIEM emitter <operation> failed for <path>: <detail>.
  • Recuperação. Isto é acionável por infraestrutura ou SecOps, não pela lógica de aplicação. Verifique o mount do volume de log, as permissões de diretório, os descritores de arquivo disponíveis e a saúde do sistema de arquivos. Uma falha de operação chain indica um sinal de adulteração ou corrupção no log de auditoria e deve ser investigada, não silenciosamente repetida.
  • Gerada quando. Um RenderManifest não pode ser construído, desserializado ou lido por causa de um erro estrutural, de tipo ou de compatibilidade de schema. O manifest é um contrato público versionado submetido por cada transporte (CLI, fila Laravel, Symfony, a API SaaS), então um manifest malformado ou incompatível é exposto diretamente em vez de ser coagido para os padrões.
  • Classe. Estende NextPdfException e sobrescreve getContext(). Construtores nomeados definem um código estável e legível por máquina no namespace SPEC-MANIFEST-*:
    • RenderManifestException::shape()SPEC-MANIFEST-001 — erro de formato ou de tipo durante RenderManifest::fromArray().
    • RenderManifestException::incompatibleVersion()SPEC-MANIFEST-002 — versão de schema major incompatível (não pode ser lida).
    • RenderManifestException::missingField()SPEC-MANIFEST-003 — campo obrigatório ausente durante a finalização do builder.
    • RenderManifestException::unsupported()SPEC-MANIFEST-004 — um manifest bem formado referencia uma entrada ou template que o renderizador atual não consegue resolver (por exemplo uma entrada de URI ou um template engine apenas de host).
  • Chaves de contexto. manifest_code (o identificador SPEC-MANIFEST-*) e reason (a descrição da falha legível por humanos). Estes também são alcançáveis por meio de getManifestCode() e getReason(). A mensagem tem a forma [<code>] <reason>.
  • Recuperação. Ramifique por manifest_code. Para SPEC-MANIFEST-001 e SPEC-MANIFEST-003, corrija o payload do manifest (corrija o tipo do campo ou forneça o campo ausente). Para SPEC-MANIFEST-002, regere o manifest contra uma versão de schema major suportada ou atualize o renderizador. Para SPEC-MANIFEST-004, forneça uma entrada ou template engine que a edição atual consiga resolver.
  • Gerada quando. A inspeção de PDF falha.
  • Classe. Estende RuntimeException diretamente (não NextPdfException), então não carrega getContext().
  • Dados carregados. Duas propriedades públicas readonly: $inspectCode (um código legível por máquina no namespace INSPECT-*) e $retryable (um booleano que indica se o chamador deve tentar novamente — por exemplo quando um sidecar de inspeção está temporariamente fora do ar). A causa de origem, quando presente, é o throwable anterior encadeado.
  • Recuperação. Ramifique por $inspectCode para a classe de falha específica. Quando $retryable for true, tente novamente com backoff porque a falha é esperada como transitória (como o reinício de um sidecar); quando false, trate a entrada ou a configuração como o defeito e não tente novamente sem alterações.
  • Gerada quando. ChaosScenarioRunner::writeReport() não consegue persistir o relatório agregado de chaos-day em disco. É uma substituição tipada de domínio para um erro de runtime genérico, para que os chamadores possam capturar a falha específica de disco do relatório sem confundi-la com erros gerados dentro dos próprios simuladores de cenário (o runner os captura como campos ChaosOutcome).
  • Classe. Estende NextPdfException e sobrescreve getContext().
  • Chaves de contexto. output_path (o caminho absoluto que o runner tentou gravar). Também é alcançável por meio de getOutputPath(). A mensagem tem a forma ChaosScenarioRunner: failed to write report to "<path>".
  • Recuperação. Esta é uma falha do lado da gravação do sink do relatório, não dos cenários. Verifique se o diretório de saída existe e é gravável e se há espaço em disco disponível, então execute novamente a gravação do relatório. Os resultados de chaos em si não são afetados.
  • Gerada quando. Um endpoint de recuperação (por exemplo um serviço de Voyage Retrieval Augmented Generation) está indisponível e o sistema recorre ao modo somente cache ou falha de forma fechada.
  • Classe. Estende NextPdfException e sobrescreve getContext().
  • Chaves de contexto. mode (o modo de operação após a falha — CACHED_ONLY quando os resultados são servidos apenas do cache semântico, ou FAIL_CLOSED quando a requisição é recusada inteiramente sem dados obsoletos) e endpoint (o endpoint que se tornou inacessível). Estes também são alcançáveis por meio de getMode() e getEndpoint(). A mensagem tem a forma Retrieval endpoint "<endpoint>" is unavailable; operating in <mode> mode.
  • Recuperação. Leia mode para saber como o sistema degradou. Sob CACHED_ONLY, os resultados podem estar obsoletos; atualize assim que o endpoint se recuperar. Sob FAIL_CLOSED, a requisição foi recusada por design e deve ser repetida após o endpoint estar acessível. Restaure a conectividade do endpoint (rede, credenciais, saúde do serviço) antes de depender de recuperação atualizada.