Source code for aeat.adapters.inbound.sanitizer._errors
"""Domain errors raised by the :mod:`adapters.inbound.sanitizer` subpackage.All sanitiser errors inherit from:class:`core.errors.AeatError` so callers can catch the familywithout importing implementation details. The hierarchy mirrors thefailure surfaces the sanitiser pipeline can encounter — source-parsefailure, signature-present refusal, already-sanitised guard, andunhandled PII surfaces."""from__future__importannotationsfrom....core.errorsimportAeatError_SANITIZER_SOURCE_LABEL="<input-pdf>"
[docs]classSanitizationError(AeatError):"""Base error for the :mod:`adapters.inbound.sanitizer` subpackage."""
[docs]classSanitizerValidationError(SanitizationError,ValueError):"""Raised when synthetic parameters or field values fail domain validation. This error inherits from both :class:`SanitizationError` and :class:`ValueError`, ensuring compatibility with Pydantic's validator contract while remaining catchable under the package's unified error hierarchy. """
[docs]classSanitizerSourceParseError(SanitizationError):"""Raised when the source PDF cannot be opened by :mod:`pikepdf`. The rendered message and structured context intentionally avoid source paths, provider payloads, and QPDF/pikepdf raw diagnostics. Callers that need to report the underlying parser failure should log only the exception type at the boundary that catches it. """def__init__(self,message:str|None=None,*,failure:str|None=None,)->None:"""Construct a redacted source-parse error. Args: message: Positional diagnostic text, intentionally not rendered or copied into context because callers may pass raw pikepdf/QPDF diagnostics here. failure: Optional underlying parser exception type name, safe for debug envelopes because it excludes operator paths and provider payload text. """context:dict[str,object]={"source":_SANITIZER_SOURCE_LABEL}iffailureisnotNone:context["failure"]=failuresuper().__init__(f"source PDF could not be opened for sanitization: {_SANITIZER_SOURCE_LABEL}",context=context,translated_message="errors.fail.fail_sanitization_source_parse",)self.failure:str|None=failure
[docs]classSignaturePresentError(SanitizationError):"""Raised when the source PDF carries a digital signature. Modifying a signed PDF silently invalidates the signature; the sanitiser refuses such inputs and requires the operator to escalate to human review. """
[docs]classAlreadySanitizedError(SanitizationError):"""Raised when the source SHA-256 is already in :data:`SANITIZED_SHAS`. Prevents accidental "re-sanitise an already-committed fixture". Callers can opt out via ``sanitize_pdf(..., refuse_if_already_sanitized=False)``. """def__init__(self,*,source_sha256:str)->None:"""Construct the error carrying the offending source hash as a typed attribute. Args: source_sha256: The SHA-256 of the source bytes that matched a known committed fixture. """super().__init__("source PDF is already a committed sanitised fixture; pass refuse_if_already_sanitized=False to override",context={"source_sha256_prefix":source_sha256[:16]},translated_message="errors.refused.refused_sanitization_already_sanitized",)self.source_sha256:str=source_sha256
[docs]classUnknownSurfaceError(SanitizationError):"""Raised when a PII surface is detected that the sanitiser does not handle. Used for threat-model surfaces this version of the sanitiser is not yet wired to scrub (e.g. a future modelo introduces an ``OCProperties`` shape we have not characterised). The default policy is *fail*; callers can downgrade to a warning by toggling the relevant ``drop_*`` flag off and accepting the resulting warning. """