summaryrefslogtreecommitdiffstats
path: root/source/cepis/exception.d
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:37:09 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:37:09 -0300
commita891657aa43d2aba06a6347dd2f94edd19afd6ba (patch)
treeb6369ed2c8485455f9c1aa707c1cd287cb8e7065 /source/cepis/exception.d
parent794f28199a4dde9d18ec711864336c96c58bb422 (diff)
downloadd-7cfbca977f267904ebcac7e10956876df780daf8.tar.gz
Carry the municipality a missing CEP would belong toHEADv0.2.0main
A 404 is rarely a random number: it is usually someone who knows the city and guessed the digits, and the classic guess is the -000 that 957 municipalities never received. The API now attaches a faixa to the not-found body naming the municipality that owns the range, so the caller can say "no such CEP, but that range is Areal/RJ" instead of only "no". It stays an error. Faixa hangs off CepNotFoundException, never off Address, and parsing is deliberately lenient: an absent, malformed or unnamed block yields a null Nullable, so reading the extra context can never cost the caller the answer it already had. cep_ini and cep_fim are the smallest and largest CEP that actually exist there, not the bounds the Correios publish, and the range between them is sparse — hence ceps, so nobody mistakes the pair for a list.
Diffstat (limited to 'source/cepis/exception.d')
-rw-r--r--source/cepis/exception.d27
1 files changed, 24 insertions, 3 deletions
diff --git a/source/cepis/exception.d b/source/cepis/exception.d
index 9b77449..d34f725 100644
--- a/source/cepis/exception.d
+++ b/source/cepis/exception.d
@@ -26,6 +26,8 @@ module cepis.exception;
import core.time : Duration;
import std.typecons : Nullable;
+import cepis.model : Faixa;
+
@safe:
/**
@@ -74,17 +76,36 @@ class InvalidCepException : CepisException
}
}
-/// The CEP is well-formed but does not exist in the DNE database.
+/**
+ * The CEP is well-formed but does not exist in the DNE database.
+ *
+ * When the API can say which municipality the number $(I would) have belonged
+ * to, that arrives in $(D faixa) and the message names it. It is $(B context
+ * for the error), not a result: the CEP still does not exist.
+ */
class CepNotFoundException : CepisException
{
/// The CEP that was looked up, unmasked.
const string cep;
+ /**
+ * The municipality whose range the CEP falls in, or null.
+ *
+ * Null whenever the API sent no usable `faixa` — including the ordinary
+ * case of a CEP in a band no municipality owns, where the API $(B omits)
+ * the field rather than sending null. Either way the lookup is still a
+ * not-found; see $(D Faixa) before showing any of it to a user.
+ */
+ const Nullable!Faixa faixa;
+
///
- this(string cep, string file = __FILE__, size_t line = __LINE__) pure nothrow
+ this(string cep, Nullable!Faixa faixa = Nullable!Faixa.init,
+ string file = __FILE__, size_t line = __LINE__) pure nothrow
{
- super("CEP " ~ cep ~ " does not exist in the DNE database", file, line);
+ super("CEP " ~ cep ~ " does not exist in the DNE database" ~ (faixa.isNull
+ ? "" : " (that range belongs to " ~ faixa.get.localidadeUf ~ ")"), file, line);
this.cep = cep;
+ this.faixa = faixa;
}
}