diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-27 20:25:04 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-27 20:53:07 -0300 |
| commit | 82d92ed4291663bae94014b4363064dbb26c6a51 (patch) | |
| tree | 69d91a59c955f1e6ec6fc0007324b5d73b3f0d01 /lib/src/errors.dart | |
| parent | 8e719fc715eb7ae9aa1c842e633f15b5c6cd3688 (diff) | |
| download | dart-3f63360ff982ef2a932eca814fdd74d4cb4b1de9.tar.gz | |
A CEP that fails a lookup is rarely a random number: it is usually someone
who knows the city and guessed the digits, and the classic guess is the
-000 that 957 municipalities never received. The API now attaches a faixa
block to the 404 naming the municipality that band belongs to, so the
caller can answer "no, but you were looking at Areal/RJ" instead of just
"no".
It stays an error. Faixa hangs off CepNotFoundException, never off Address,
and cepIni/cepFim are the extremes that actually exist in the municipality
rather than the range the Correios publish — echoing back the published
start would return the very CEP that just failed. The interval is sparse,
which is what ceps is for; it is not a list of alternatives.
Parsing is deliberately forgiving: a missing, empty or malformed block is
null. Losing a clean not-found to a parse error over the hint attached to
it would be a bad trade.
Diffstat (limited to 'lib/src/errors.dart')
| -rw-r--r-- | lib/src/errors.dart | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/lib/src/errors.dart b/lib/src/errors.dart index 24b35c4..be32b25 100644 --- a/lib/src/errors.dart +++ b/lib/src/errors.dart @@ -18,6 +18,8 @@ /// all, when the CEP is malformed before it ever leaves the machine. library; +import 'models.dart'; + /// Base of every error this library throws. Catch this to handle any failure. /// /// Sealed: the subtypes below are the complete set, so a `switch` on one is @@ -59,12 +61,40 @@ final class InvalidCepException extends CepisException } /// The CEP is well-formed but does not exist in the DNE database. +/// +/// [faixa] may name the municipality the CEP would have belonged to. It does +/// not soften the error: this is still a 404, and there is still no address. final class CepNotFoundException extends CepisException { - /// Creates the error for [message], recording the normalised [cep]. - const CepNotFoundException(super.message, {this.cep}); + /// Creates the error for [message], recording the normalised [cep] and the + /// [faixa] the API named, when it named one. + const CepNotFoundException(super.message, {this.cep, this.faixa}); /// The CEP that was looked up, normalised to 8 digits. final String? cep; + + /// The municipality that owns the numeric band this CEP fell in, or `null`. + /// + /// `null` when the CEP falls in a band no municipality owns — the API + /// **omits** the block there rather than sending null — and also whenever the + /// block cannot be read. See [Faixa], and read [Faixa.cepIni]/[Faixa.cepFim] + /// as the extremes that exist, not as a range of valid CEPs. + final Faixa? faixa; + + /// Mentions the municipality when the API named one. + /// + /// The count comes along deliberately: `118 CEPs` across nearly five + /// thousand numbers is what stops the two bounds from reading like a range + /// where anything in between would work. + @override + String toString() { + final band = faixa; + if (band == null) { + return super.toString(); + } + return '$runtimeType: $message — that band belongs to ' + '${band.localidade}/${band.uf}, which has ${band.ceps} CEPs scattered ' + 'between ${band.cepIni} and ${band.cepFim}'; + } } /// The request never completed: DNS, refused connection, timeout, TLS. |