diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-27 20:31:30 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-27 20:31:30 -0300 |
| commit | 67276c6444a70b61030ab3ee52b84dc5014af0e8 (patch) | |
| tree | ac0246ed287c6aec57e335403b20b23214ec4eb0 /README.md | |
| parent | 64764fb9fac0227f8e0443e7c7519d73aec275b9 (diff) | |
| download | php-0.2.0.tar.gz | |
The API now sends an optional faixa block on the 404 of GET /{cep}, naming
the municipality the CEP would have belonged to. That failing CEP is rarely
random: it is usually someone who knows the city and guessed the number,
most often the -000 that 957 municipalities never received. Knowing the
lookup failed "in Areal/RJ" is the difference between a message a user can
act on and a bare "CEP not found".
It stays an error. Faixa hangs off CepNotFoundException, never off Address,
and parsing is deliberately forgiving: a missing, empty or malformed block
yields null rather than turning a clean not-found into a parse failure.
Its cep_ini/cep_fim are the CEPs that exist, not the bounds the Correios
publish, and the interval between them is sparse -- hence ceps, and hence
the docblocks insisting the pair is not a list of valid CEPs.
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 56 |
1 files changed, 55 insertions, 1 deletions
@@ -233,7 +233,7 @@ the HTTP 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 | | `ServerErrorException` | 5xx; carries `status` | yes, later | | `NetworkException` | DNS, connection, timeout, TLS | yes, later | @@ -264,6 +264,60 @@ an `\InvalidArgumentException` and `CepNotFoundException` is an 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. +### A CEP that does not exist, but in a city that does + +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`, which 957 +municipalities never received. So `CepNotFoundException` carries a `Faixa` when +the API can say which municipality the CEP *would* have belonged to: + +```php +try { + $address = Client::default()->lookup('25845-000'); +} catch (CepNotFoundException $e) { + if ($e->faixa !== null) { + printf( + "CEP not found in %s — the city has %d CEPs, between %s and %s\n", + $e->faixa->label(), // "Areal/RJ" + $e->faixa->ceps, // 118 + $e->faixa->cep_ini, // "25845001" + $e->faixa->cep_fim, // "25849899" + ); + } +} +``` + +It is still a 404. **`faixa` is context for an error, never an address**: a CEP +that has one is just as absent from the database as one that does not, and +nothing here should turn a not-found into a success. What it buys you is a +message worth reading — *"we could not find that CEP in Areal/RJ"* instead of +*"CEP not found"*. + +`$e->faixa` is null whenever the API sent nothing, which is what happens for a +CEP in a band no municipality owns. The field is **omitted, never null**, so +absence is normal; and a `faixa` this client cannot read is also null, because a +malformed block must never cost you the exception you came for. + +| field | | +| --- | --- | +| `localidade`, `uf`, `estado`, `regiao`, `ibge` | the municipality, same keys as on `Address` | +| `cep_ini`, `cep_fim` | the smallest and largest CEP that **exist** there | +| `ceps` | how many CEPs the municipality actually has | +| `label()` | `"Areal/RJ"`, for showing to a person | + +Two things about the range, both easy to get wrong: + +`cep_ini` and `cep_fim` are **not** the bounds the Correios publish. They are +the extremes of what is really in the database. The DNE's own start for Areal is +`25845000` — exactly the CEP that failed above — and it is not `cep_ini` +precisely because it does not exist. + +**The range is sparse.** Areal's 118 CEPs are spread across the ~4,900 numbers +between `25845001` and `25849899`; almost all of that interval is empty. That is +what `ceps` is for. Never iterate the interval, never present the pair as the +list of valid CEPs for the city, and never conclude from +`cep_ini <= $x <= cep_fim` that `$x` exists. + ## Development Everything runs through `make`: |