diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-27 20:37:05 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-27 20:44:20 -0300 |
| commit | eb15ec9b2715783fcd2bf4f834595d1bd549c09d (patch) | |
| tree | cd9c6e80892b409db346fde3fe8334f3c37a1130 /src/util.c | |
| parent | e2c6ae13af335b311da2429c903032124f926df2 (diff) | |
| download | c-a90051dad5efd24e867396ad840afa4d01a4d3ef.tar.gz | |
A CEP that fails is rarely a random number. It is usually someone who
knows the city and guessed the last 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 the CEP would have
belonged to, and telling a caller "that CEP does not exist, did you mean
somewhere in Areal/RJ?" is worth far more than telling them "no".
It rides on cepis_error_t rather than on cepis_address_t because it is
context for a failure, not an address: the lookup still returns
CEPIS_ERR_NOT_FOUND and still hands back no address. Embedded by value
with a has_faixa flag, so the error keeps owning nothing and keeps
living on the stack with nothing to free; cepis_error_faixa gives the
absent case the same NULL-or-not shape as cepis_address_t::geo, which is
what the API's omit-never-null encoding calls for.
Parsing is total on purpose. A body that is not JSON, a faixa that is
null, a string, an array, or an object with no localidade all mean "the
API named no municipality". A 404 is already the answer, and failing to
read the garnish must never turn it into a different one.
The bounds need reading with care, hence the length of the comments:
cep_ini and cep_fim are the smallest and largest CEP that actually
exist, not the range the Correios publish -- the DNE's own start for
Areal is 25845000, exactly the CEP that just failed -- and the range is
sparse, 118 CEPs scattered over the ~4900 numbers up to 25849899. That
is what ceps is for.
Diffstat (limited to 'src/util.c')
| -rw-r--r-- | src/util.c | 6 |
1 files changed, 6 insertions, 0 deletions
@@ -71,6 +71,12 @@ cepis_status_t cepis_set_error(cepis_error_t *err, cepis_status_t status, err->status = status; err->http_status = http_status; err->retry_after = retry_after; + /* + * Cleared here, not by the caller: an error is declared uninitialised + * on the stack and reused across calls, so anything left set would be + * read as a municipality that this failure never named. + */ + err->has_faixa = false; va_start(args, fmt); vsnprintf(err->message, sizeof(err->message), fmt, args); va_end(args); |