diff options
Diffstat (limited to 'cepis/client.lua')
| -rw-r--r-- | cepis/client.lua | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/cepis/client.lua b/cepis/client.lua index 2a8ae2c..d8a42c9 100644 --- a/cepis/client.lua +++ b/cepis/client.lua @@ -24,7 +24,7 @@ local csv = require("cepis.csv") local M = {} --- Library version, as it appears in the default `User-Agent`. -M.VERSION = "0.1.0" +M.VERSION = "0.2.0" --- Where the API lives unless `base_url` says otherwise. M.DEFAULT_URL = "https://cep.is" @@ -191,6 +191,22 @@ local function error_message(body, fallback) return fallback end +--- The `faixa` of a 404 body, when it carries one. +-- +-- Every step is allowed to give up and return `nil`: the body may not be JSON +-- at all (an edge answering instead of the API), may not carry the block (the +-- API omits it, never nulls it, for a CEP in a band no municipality owns), or +-- may carry something unusable. None of that may turn a clean not-found into a +-- parse failure — the answer to the caller is the same 404 either way, only +-- with less context on it. +local function faixa_from(body) + local ok, data = pcall(json.decode, body or "", 1, nil) + if not ok or type(data) ~= "table" then + return nil + end + return models.new_faixa(data.faixa) +end + local function transport(url) if url:lower():find("^https://") then local ok, https = pcall(require, "ssl.https") @@ -430,6 +446,15 @@ end -- the format already passed local validation, so the server knows something -- this client does not. -- +-- A `not_found` may carry `err.faixa`, a `Faixa` naming the municipality the +-- CEP would have belonged to. It is context for the failure and nothing more — +-- the lookup still failed, and it is `nil` whenever the API omits the block: +-- +-- local address, err = client:lookup("25845000") +-- if not address and err.kind == cepis.NOT_FOUND and err.faixa then +-- print("did you mean a CEP in " .. err.faixa:label() .. "?") +-- end +-- -- @tparam string cep masked or unmasked -- @treturn[1] Address -- @treturn[2] nil @@ -448,12 +473,17 @@ function Client:lookup(cep) end if status == 404 then + local faixa = faixa_from(body) + local message = "CEP " .. number .. " does not exist in the DNE database" + if faixa then + message = message .. ", which would place it in " .. faixa:label() + end return nil, - errors.new( - errors.NOT_FOUND, - "CEP " .. number .. " does not exist in the DNE database", - { cep = number, status = 404 } - ) + errors.new(errors.NOT_FOUND, message, { + cep = number, + status = 404, + faixa = faixa, + }) end if status == 400 then return nil, |