Created
December 2, 2022 15:06
-
-
Save mbezjak/c1baeece563b8ed734692938e6d1a36f to your computer and use it in GitHub Desktop.
Error model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns my.company.error | |
"Error carries error information as a hash-map. | |
A hash-map can carry any information. Some information is system wide (thus | |
used by the system) and will be promoted as qualified keywords not to conflict | |
with user defined ones. Those are: | |
- `:code` [qualified keyword] - error code | |
- `:args` [collection] - arguments for `format` to build the error message | |
- `:message` [string] - a human error message | |
- `:breadcrumbs` [collection] - a path to the source that caused the error | |
- `:suggested-http-code` [int] - HTTP status code of the response | |
To construct an error, use one of constructor functions: | |
- `make` | |
- `from-message` | |
Only access system wide information using the accessor functions below and | |
never as a fully qualified keyword because that is an implementation detail | |
and might be subject to change." | |
(:require | |
[clojure.set :as set] | |
[clojure.string :as string])) | |
(def ^:private promoted-attributes | |
{:code ::code | |
:args ::args | |
:message ::message | |
:breadcrumbs ::breadcrumbs | |
:suggested-http-code ::suggested-http-code}) | |
(defn code [e] | |
(::code e)) | |
(defn args [e] | |
(::args e)) | |
(defn message [e] | |
(::message e)) | |
(defn breadcrumbs [e] | |
(::breadcrumbs e)) | |
(defn suggested-http-code [e] | |
(::suggested-http-code e)) | |
(defn- ensure-code-is-qualified-keyword! [e] | |
(let [c (code e)] | |
(when (and c (not (qualified-keyword? c))) | |
(throw (IllegalArgumentException. (format "Code must be qualified keyword, but was: %s with type %s" | |
c (type c))))))) | |
(defn make [e] | |
(let [promoted (merge {} | |
(set/rename-keys e promoted-attributes) | |
(apply dissoc e (keys promoted-attributes)))] | |
(ensure-code-is-qualified-keyword! promoted) | |
promoted)) | |
(defn from-message [message] | |
(make {:message message})) | |
(defn set-suggested-http-code [e http-code] | |
(make (assoc e :suggested-http-code http-code))) | |
(defn format-args [e] | |
(map (fn [a] | |
(cond | |
;; Want extensibility? Use defprotocol | |
(nil? a) "null" | |
(string? a) a | |
(coll? a) (string/join ", " (sort a)) | |
:else a)) | |
(args e))) | |
(defn- ensure-message-template-exists! [tpl e] | |
(when-not tpl | |
(throw (ex-info (format "Message template doesn't exist for code: %s" (code e)) | |
{:error e})))) | |
(defn with-message [e template-map] | |
(if (message e) | |
e | |
(let [tpl (get template-map (code e)) | |
_ (ensure-message-template-exists! tpl e) | |
as (seq (format-args e)) | |
msg (if as (apply format tpl as) tpl)] | |
(make (assoc e :message msg))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns my.company.errors | |
"Errors is a collection of `error`." | |
(:require | |
[my.company.error :as error])) | |
(defn make [es] | |
(mapv error/make es)) | |
(defn make-1 [e] | |
(make [e])) | |
(defn codes [es] | |
(mapv error/code es)) | |
(defn messages [es] | |
(mapv error/message es)) | |
(defn set-suggested-http-code [http-code es] | |
(mapv #(error/set-suggested-http-code % http-code) es)) | |
(defn suggested-http-code [es] | |
(->> es | |
(map error/suggested-http-code) | |
(remove nil?) | |
(first))) | |
(defn with-message [template-map es] | |
(mapv #(error/with-message % template-map) es)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment