summaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:34:36 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:34:36 -0300
commitf2f3e5b5b22f5db49670391fb747a52fd492b9db (patch)
tree3d02d13f3111bdd7381470d3fd3db1f58e00bc8c /README.md
parent0bc578d6d334c7f1ccaf329cd61bb8bce76b7f59 (diff)
downloadperl-0.2.0.tar.gz
Carry the municipality on a CEP that does not existHEADv0.2.0main
A CEP that fails 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 answers those 404s with a faixa block naming the municipality that owns the band, so the library can say "25845000 does not exist in Areal/RJ" instead of "not found". It stays an error: lookup still throws Cepis::Error::CEPNotFound, and the faixa hangs off the exception rather than turning a miss into an address. Parsing it is deliberately forgiving — a missing, empty or malformed block yields undef, because losing the clean not-found to a parse failure would be a worse outcome than losing the context. cep_ini and cep_fim are the smallest and largest CEP that actually exist, not the bounds the Correios publish, and the interval between them is sparse. That is why ceps is exposed alongside them and why the docs say twice that the pair is not a list of valid CEPs.
Diffstat (limited to 'README.md')
-rw-r--r--README.md48
1 files changed, 47 insertions, 1 deletions
diff --git a/README.md b/README.md
index b799f45..48336b3 100644
--- a/README.md
+++ b/README.md
@@ -252,6 +252,52 @@ Errors stringify to their message, so `warn $err` and `"$err"` do the obvious
thing. `$err->retry_after` carries what the server asked for, in seconds, and
`$err->status` the HTTP status of the last attempt.
+### A not-found that knows where it was
+
+A `Cepis::Error::CEPNotFound` often knows **which municipality** the CEP would
+have belonged to. When it does, `$err->faixa` is a `Cepis::Faixa`:
+
+```perl
+my $address = eval { Cepis::lookup('25845000') };
+
+if ( !$address && ref $@ && $@->isa('Cepis::Error::CEPNotFound') ) {
+ if ( my $faixa = $@->faixa ) {
+ $faixa->localidade; # "Areal"
+ $faixa->uf; # "RJ"
+ $faixa->ibge; # "3300225"
+ $faixa->ceps; # 118
+ $faixa->cep_ini; # "25845001"
+ $faixa->cep_fim; # "25849899"
+ $faixa->label; # "Areal/RJ"
+ }
+}
+```
+
+The message names the municipality too:
+
+```
+CEP 25845000 does not exist in the DNE database (it would fall in Areal/RJ)
+```
+
+Worth checking, because a failing CEP is rarely random: it is usually someone
+who knows the city and guessed the number, and the classic guess is the `-000`
+that 957 municipalities never received.
+
+Three things this is not:
+
+- **It is not a success.** The response is still a 404 and `lookup` still
+ throws. `faixa` is context for the error, never an address.
+- **It is not always there.** When the CEP falls in a band no municipality owns,
+ the API omits the block — `$err->faixa` is then `undef`, never a null-ish
+ empty object. A malformed block is dropped the same way rather than turning a
+ clean not-found into a parse failure.
+- **`cep_ini`..`cep_fim` is not a list of valid CEPs.** They are the smallest
+ and the largest CEP that *actually exist* there, not the bounds the Correios
+ publish — the DNE's own start for Areal is `25845000`, exactly the CEP that
+ just failed. And the range is sparse: Areal's 118 CEPs are scattered across
+ the ~4,900 numbers between them. That is what `ceps` is for. Do not iterate
+ the interval.
+
`Cepis::Error::InvalidResponse` almost always means something between you and
the API is answering instead of it — a captive Wi-Fi portal, a corporate proxy,
an HTML error page. Useful as a diagnosis: the problem is not in your code.
@@ -269,7 +315,7 @@ bring up a real HTTP server on loopback.
make # list the targets
make test # run the suite with prove
make lint # perl -c over lib, t and Makefile.PL
-make build # build Cepis-0.1.0.tar.gz
+make build # build Cepis-0.2.0.tar.gz
make check # lint, then test, then build
```