summaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:33:51 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:33:51 -0300
commit2fb251996798798af38903fe535b8d147084a50a (patch)
tree9bcbb6ead9c7c4c1910495186707dc0f8859169d /README.md
parentb71faa6e95a0736f1ff171e006b171467b65db90 (diff)
downloadcpp-492ee0a03b6f23c3459cd32694cb1ed6bffdf014.tar.gz
Expose the municipality behind a not-found CEPHEADv0.2.0main
A CEP that fails a lookup 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. The API now names, on the 404 itself, the municipality that CEP would have belonged to, so a caller can say "not found — did you mean somewhere in Areal/RJ?" instead of just "not found". CepNotFound carries it as an optional Faixa. It stays an error: the block is context, not an address, and the range it describes is sparse, which is why it reports a count alongside the first and last CEP that actually exist there rather than the bounds the Correios publish. Parsing it is best-effort on purpose — a missing, empty or malformed block leaves the optional empty, since a 404 is already the answer and reading the hint attached to it must never cost the diagnosis.
Diffstat (limited to 'README.md')
-rw-r--r--README.md40
1 files changed, 39 insertions, 1 deletions
diff --git a/README.md b/README.md
index 0b85199..876a819 100644
--- a/README.md
+++ b/README.md
@@ -193,7 +193,7 @@ make**, not by the HTTP status that caused it:
| error | when | does retrying help? |
| --- | --- | --- |
| `InvalidCep` | not 8 digits | no |
-| `CepNotFound` | well-formed, not in the database | no |
+| `CepNotFound` | well-formed, not in the database; may expose `faixa()` | no |
| `RateLimited` | 429; exposes `retry_after()` | yes, later |
| `ServerError` | 5xx; exposes `status()` | yes, later |
| `NetworkError` | DNS, connection, timeout, TLS | yes, later |
@@ -209,6 +209,44 @@ try {
}
```
+### A CEP that does not exist
+
+`CepNotFound` often knows **where the CEP would have been**. A CEP that fails
+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.
+
+```cpp
+try {
+ const cepis::Address a = cepis::lookup("25845-000");
+} catch (const cepis::CepNotFound& error) {
+ if (error.faixa()) {
+ error.faixa()->localidade; // "Areal"
+ error.faixa()->uf; // "RJ"
+ error.faixa()->ibge; // "3300225"
+ error.faixa()->cep_ini; // "25845001"
+ error.faixa()->cep_fim; // "25849899"
+ error.faixa()->ceps; // 118
+ }
+}
+```
+
+Three things to keep straight:
+
+- **It is still a 404.** `faixa` is context for an error, not an address. The
+ CEP does not exist; nothing here makes it deliverable.
+- **`cep_ini` and `cep_fim` are the CEPs that actually exist**, not the bounds
+ the Correios publish. The DNE's own start for Areal is `25845000` — 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 a list of valid CEPs.
+
+When the CEP falls in a band no municipality owns, the API **omits** `faixa`
+entirely — it never sends null — and `error.faixa()` is empty. A block that
+cannot be read is empty too: a 404 is already the answer, and failing to read
+the hint attached to it never turns into a parse 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.