From b199ae044f8f9cd4b745214cd5e5495f86b5eb54 Mon Sep 17 00:00:00 2001 From: Murilo Ijanc Date: Mon, 27 Jul 2026 20:32:01 -0300 Subject: Carry the municipality of a CEP that does not exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A failing CEP is rarely random: it is someone who knows the city and guessed the number, and the classic guess is the -000 that 957 municipalities never received. The API now answers those 404s with a faixa block naming the municipality the CEP would have belonged to, so a caller can ask "did you mean somewhere in Areal/RJ?" instead of "invalid CEP". CEPNotFound gains faixa, defaulting to None. It stays a 404 and stays an exception — the field is context for the error, never a demotion of it into a partial success. Parsing is deliberately total: anything missing, empty or malformed under faixa yields None, because turning a clean not-found into a parse failure over an optional courtesy field would be strictly worse than not having the field at all. Faixa's cep_ini/cep_fim are the smallest and largest CEP that actually exist there, not the bounds the Correios publish, and the range in between is sparse — hence ceps, so the pair is never read as a list of valid numbers. --- src/cepis/errors.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/cepis/errors.py') diff --git a/src/cepis/errors.py b/src/cepis/errors.py index 1698972..12862df 100644 --- a/src/cepis/errors.py +++ b/src/cepis/errors.py @@ -19,6 +19,8 @@ before it ever leaves the machine. from __future__ import annotations +from .models import Faixa + class CepisError(Exception): """Base of every error. Catch this to handle any failure.""" @@ -45,8 +47,19 @@ class CEPNotFound(CepisError, KeyError): `KeyError.__str__` wraps the message in quotes (inherited from dict behaviour), which is why `__str__` is overridden here — otherwise every message would come out with spurious quotes around it. + + `faixa` is the municipality the CEP *would* have belonged to, when the API + could work it out: see :class:`cepis.Faixa`. It is `None` whenever the API + did not say — either because the CEP falls in a band no municipality owns, + or because the server is older than this field. Either way the exception is + the same exception: `faixa` is context for the error, never a demotion of + it into a partial success. """ + def __init__(self, message: str, faixa: Faixa | None = None) -> None: + super().__init__(message) + self.faixa = faixa + def __str__(self) -> str: return self.args[0] if self.args else "" -- cgit v1.3