summaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md36
1 files changed, 35 insertions, 1 deletions
diff --git a/README.md b/README.md
index 4e1a18f..94b5daa 100644
--- a/README.md
+++ b/README.md
@@ -157,7 +157,7 @@ decision you have to make**, not by the HTTP status that caused it:
| error | when | does retrying help? |
| --- | --- | --- |
| `Invalid_cep` | not 8 digits | no |
-| `Cep_not_found` | well-formed, not in the database | no |
+| `Cep_not_found` | well-formed, not in the database; may carry `faixa` | no |
| `Rate_limited` | 429; carries `retry_after` | yes, later |
| `Server_error` | 5xx; carries `status` | yes, later |
| `Network_error` | DNS, connection, timeout, TLS | yes, later |
@@ -170,6 +170,40 @@ match Cepis.lookup cep_from_form with
| Error _ -> reschedule ()
```
+### Not found: which city it would have been
+
+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. So `Cep_not_found` carries a `faixa` naming the
+municipality whose band that number falls into, when it falls into one:
+
+```ocaml
+match Cepis.lookup "25845000" with
+| Error (Cepis.Cep_not_found { faixa = Some f; _ }) ->
+ Printf.printf "not found — did you mean somewhere in %s/%s? (%d CEPs, %s to %s)\n"
+ f.Cepis.localidade f.Cepis.uf f.Cepis.ceps f.Cepis.cep_ini f.Cepis.cep_fim
+ (* not found — did you mean somewhere in Areal/RJ? (118 CEPs, 25845001 to 25849899) *)
+| Error (Cepis.Cep_not_found { faixa = None; _ }) -> ask_for_another_cep ()
+| _ -> ()
+```
+
+Three things this is not:
+
+- **It is still not found.** The lookup failed; `faixa` is context on the
+ error, never an address. Nothing here says the CEP exists.
+- **`cep_ini`/`cep_fim` are not the Correios' published bounds.** They are the
+ smallest and largest CEP that *actually exist* in that municipality. The
+ DNE's own start for Areal is `25845000` — exactly the CEP that just failed.
+- **The pair is not a list of valid CEPs.** 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. Rendering it as "valid from … to …"
+ would be wrong for about 98% of the interval.
+
+`faixa` is `None` when the CEP lands in a band no municipality owns — the API
+omits the field rather than sending null — and also whenever it cannot be read.
+A 404 is a clean answer, and no shape of `faixa` turns it into an
+`Invalid_response`.
+
`Invalid_response` 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.