summaryrefslogtreecommitdiffstats
path: root/cepis/client.lua
diff options
context:
space:
mode:
Diffstat (limited to 'cepis/client.lua')
-rw-r--r--cepis/client.lua42
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,