diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-27 20:37:09 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-27 20:37:09 -0300 |
| commit | a891657aa43d2aba06a6347dd2f94edd19afd6ba (patch) | |
| tree | b6369ed2c8485455f9c1aa707c1cd287cb8e7065 /README.md | |
| parent | 794f28199a4dde9d18ec711864336c96c58bb422 (diff) | |
| download | d-0.2.0.tar.gz | |
A 404 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 to the
not-found body naming the municipality that owns the range, so the caller
can say "no such CEP, but that range is Areal/RJ" instead of only "no".
It stays an error. Faixa hangs off CepNotFoundException, never off
Address, and parsing is deliberately lenient: an absent, malformed or
unnamed block yields a null Nullable, so reading the extra context can
never cost the caller the answer it already had.
cep_ini and cep_fim are the smallest and largest CEP that actually exist
there, not the bounds the Correios publish, and the range between them is
sparse — hence ceps, so nobody mistakes the pair for a list.
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 47 |
1 files changed, 45 insertions, 2 deletions
@@ -21,7 +21,7 @@ Or in `dub.json`: ```json "dependencies": { - "cepis": "~>0.1.0" + "cepis": "~>0.2.0" } ``` @@ -166,7 +166,7 @@ status that caused it: | exception | when | does retrying help? | | --- | --- | --- | | `InvalidCepException` | not 8 digits | no | -| `CepNotFoundException` | well-formed, not in the database | no | +| `CepNotFoundException` | well-formed, not in the database; may carry `faixa` | no | | `RateLimitedException` | 429; carries `retryAfter` | yes, later | | `ServerException` | 5xx; carries `status` | yes, later | | `NetworkException` | DNS, connection, timeout, TLS | yes, later | @@ -190,6 +190,49 @@ catch (CepisException error) 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. +### When the CEP does not exist + +A 404 sometimes knows *where* the CEP would have been. `CepNotFoundException` +carries it in `faixa`: the municipality that owns the range the number falls +in. + +```d +try + render(lookup("25845-000")); +catch (CepNotFoundException error) +{ + if (error.faixa.isNull) + askForAnotherCep(); + else + { + auto f = error.faixa.get; + writeln("no such CEP — that range is ", f.localidade, "/", f.uf); + writeln(f.ceps, " CEPs, from ", f.cep_ini, " to ", f.cep_fim); + // 118 CEPs, from 25845001 to 25849899 + } +} +``` + +It is **context for an error, not an address.** The status is still 404 and the +CEP still does not exist; `faixa` never becomes an `Address` and must not be +rendered as if the lookup had worked. + +`cep_ini` and `cep_fim` 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`, which is exactly the CEP that just failed. + +The range is **sparse**: Areal's 118 CEPs are scattered across the ~4,900 +numbers between `25845001` and `25849899`. That is what `ceps` is for. Never +present the pair as the list of valid CEPs for the city, and do not walk it +expecting the numbers in between to resolve. + +`faixa` is null whenever the API sent none — and it is **omitted, never null**, +when the CEP falls in a band no municipality owns. + +Why it exists: a CEP that fails is rarely a random number, it is someone who +knows the city and guessed the digits — and the classic guess is the `-000` +that 957 municipalities never received. + ## Development Everything runs through `make`, which shells out to `dub`: |