summaryrefslogtreecommitdiffstats
path: root/src/errors.lisp
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-26 12:42:28 -0300
committerMurilo Ijanc <[email protected]>2026-07-26 12:42:28 -0300
commitae9ad8a4c61b793f6859c84dac80b1c1b04b7b68 (patch)
tree62271e7672dfc58f59dda2ea4dc539c89a1ea5ca /src/errors.lisp
downloadlisp-ae9ad8a4c61b793f6859c84dac80b1c1b04b7b68.tar.gz
Initial importv0.1.0
Diffstat (limited to 'src/errors.lisp')
-rw-r--r--src/errors.lisp73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/errors.lisp b/src/errors.lisp
new file mode 100644
index 0000000..525ac67
--- /dev/null
+++ b/src/errors.lisp
@@ -0,0 +1,73 @@
+(in-package #:cepis)
+
+(define-condition cepis-error (error)
+ ((message :initarg :message
+ :initform ""
+ :reader error-message
+ :documentation "The human-readable description of the failure."))
+ (:report (lambda (condition stream)
+ (write-string (error-message condition) stream)))
+ (:documentation
+ "Base of every error this library signals. Handle it to catch any failure.
+
+Below it the split is by the decision the caller has to make, not by the HTTP
+status that caused it. `invalid-cep' and `cep-not-found' are problems with the
+request: retrying is pointless, the same CEP will fail again. `network-error',
+`server-error' and `rate-limited' are problems with transport: retrying may
+help, and the client already retried on its own before signalling any of
+them."))
+
+(define-condition invalid-cep (cepis-error parse-error)
+ ()
+ (:documentation
+ "The CEP is not 8 digits.
+
+Deliberately also a `parse-error': turning a string into a CEP is a parse, and
+code that already handles `parse-error' while validating input keeps working
+without knowing this library exists.
+
+Usually signalled without a request ever being made — the client checks the
+format before going to the network."))
+
+(define-condition cep-not-found (cepis-error cell-error)
+ ()
+ (:documentation
+ "The CEP is well-formed but does not exist in the DNE database.
+
+Also a `cell-error', which is the closest thing the standard has to a failed
+key lookup: `cell-error-name' returns the CEP that was not found."))
+
+(define-condition network-error (cepis-error)
+ ()
+ (:documentation
+ "The request never completed: DNS, refused connection, timeout, TLS.
+
+Signalled only after every configured attempt has failed."))
+
+(define-condition server-error (cepis-error)
+ ((status :initarg :status
+ :initform 0
+ :reader server-error-status
+ :documentation "The HTTP status seen on the last attempt."))
+ (:documentation "The API answered 5xx on every attempt."))
+
+(define-condition rate-limited (cepis-error)
+ ((retry-after :initarg :retry-after
+ :initform nil
+ :reader rate-limited-retry-after
+ :documentation
+ "What the server asked for, in seconds, or NIL if it did not say."))
+ (:documentation
+ "The API (or the edge in front of it) answered 429.
+
+The client already honoured `rate-limited-retry-after' across the attempts it
+made; it is exposed here for callers who want to reschedule the work."))
+
+(define-condition invalid-response (cepis-error)
+ ()
+ (:documentation
+ "A success status came back with a body that cannot be parsed.
+
+In practice this 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."))