Skip to content

Commit 89e8c2f

Browse files
authored
Merge pull request #15 from liquidz/dev
Next release
2 parents 1e3b525 + 76b09cd commit 89e8c2f

File tree

9 files changed

+216
-116
lines changed

9 files changed

+216
-116
lines changed

Makefile

+15-31
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,51 @@
11
CP=$(shell clojure -A:dev -Spath)
22

3-
.PHONY: repl
4-
repl:
5-
iced repl -A:dev --with-kaocha --force-clojure-cli
3+
.PHONY: help
4+
help:
5+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
66

77
.PHONY: repl-cljs
8-
repl-cljs:
9-
@npx nbb --classpath "$(shell clojure -A:dev -Spath)" nrepl-server
10-
11-
.PHONY: inspect
12-
inspect:
13-
node --inspect target/js/compiled/index.js
8+
repl-cljs: ## Start cljs REPL via nbb
9+
@npx nbb --classpath "$(CP)" nrepl-server
1410

1511
.PHONY: test
16-
test: test-clj test-bb test-cljs test-nbb
12+
test: test-clj test-bb test-cljs test-nbb ## Run all tests
1713

1814
.PHONY: test-clj
19-
test-clj:
15+
test-clj: ## Run clj tests
2016
clojure -M:dev:1.9:test-clj
2117
clojure -M:dev:1.10:test-clj
2218
clojure -M:dev:test-clj
2319

2420
.PHONY: test-bb
25-
test-bb:
21+
test-bb: ## Run babashka tests
2622
@bb --classpath "$(CP)" bb_test_runner.clj
2723

2824
.PHONY: test-cljs
29-
test-cljs:
25+
test-cljs: ## Run cljs tests
3026
@clojure -M:dev:test-cljs
3127

3228
.PHONY: test-nbb
33-
test-nbb:
29+
test-nbb: ## Run nbb tests
3430
@npx nbb --classpath "$(CP)" bb_test_runner.clj
3531

3632
.PHONY: clean
37-
clean:
33+
clean: ## Clean
3834
rm -rf node_modules target .cpcache .clj-kondo/.cache
3935

4036
.PHONY: lint
41-
lint:
37+
lint: ## Check lint errors and format errors
4238
clj-kondo --lint src:test
4339
cljstyle check
4440

4541
.PHONY: outdated
46-
outdated:
42+
outdated: ## Show and upgrade outdated dependencies
4743
clojure -M:outdated --upgrade
4844

49-
.PHONY: pom
50-
pom:
51-
clojure -T:build pom
52-
53-
.PHONY: jar
54-
jar:
55-
clojure -T:build jar
56-
5745
.PHONY: install
58-
install: clean
46+
install: clean ## Install jar to the local Maven repository
5947
clojure -T:build install
6048

61-
.PHONY: deploy
62-
deploy: clean
63-
clojure -T:build deploy
64-
6549
.PHONY: coverage
66-
coverage:
50+
coverage: ## Show coverage
6751
clojure -M:coverage:dev --src-ns-path=src --test-ns-path=test --codecov

README.adoc

+39-8
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ This library is based on https://adambard.com/blog/acceptable-error-handling-in-
2727
;; (require '[merr.core :as merr :include-macros true])
2828
2929
(merr/let +err+ [foo 1
30-
bar (merr/err)
30+
bar (merr/error)
3131
baz (* bar 2)]
3232
{:+err+ +err+ :foo foo :bar bar :baz baz})
33-
;; => {:+err+ (merr/err), :foo 1, :bar nil, :baz nil}
33+
;; => {:+err+ (merr/error), :foo 1, :bar nil, :baz nil}
3434
----
3535

3636
== Usage
@@ -55,7 +55,7 @@ This library is based on https://adambard.com/blog/acceptable-error-handling-in-
5555
;; => "c = 12"
5656
5757
(merr/let err [a 10
58-
b (merr/err {:message "ERROR"})
58+
b (merr/error {:message "ERROR"})
5959
c (inc b)]
6060
(if err
6161
(merr/message err)
@@ -70,8 +70,8 @@ This library is based on https://adambard.com/blog/acceptable-error-handling-in-
7070
(merr/-> 10 (+ 1) (- 1))
7171
;; => 10
7272
73-
(merr/-> 10 ((fn [_] (merr/err))) (- 1))
74-
;; => (merr/err)
73+
(merr/-> 10 ((fn [_] (merr/error))) (- 1))
74+
;; => (merr/error)
7575
----
7676

7777
=== `->>`
@@ -81,16 +81,47 @@ This library is based on https://adambard.com/blog/acceptable-error-handling-in-
8181
(merr/->> 10 (+ 1) (- 1))
8282
;; => -10
8383
84-
(merr/->> 10 ((fn [_] (merr/err))) (- 1))
85-
;; => (merr/err)
84+
(merr/->> 10 ((fn [_] (merr/error))) (- 1))
85+
;; => (merr/error)
8686
----
8787

8888
=== `try`
8989

9090
[source,clojure]
9191
----
9292
(merr/try (throw (ex-info "ERROR" {})))
93-
;; => merr/err?
93+
;; => merr/error?
94+
----
95+
96+
== Custom error
97+
98+
You can specify any keywords as `:type`, but you may want to define and use specific `:type` of errors in your project.
99+
In that case, `merr.helper` is useful.
100+
101+
[source,clojure]
102+
----
103+
(require '[merr.helper :as merr.h])
104+
;; => nil
105+
106+
(def custom-error (partial merr.h/typed-error ::custom-error-type))
107+
;; => var?
108+
109+
(def custom-error? (partial merr.h/typed-error? ::custom-error-type))
110+
;; => var?
111+
112+
(custom-error? (custom-error {:message "custom error"}))
113+
;; => true
114+
----
115+
116+
`typed-error?` will check child error types, so you can define sub errors via `clojure.core/derive`.
117+
118+
[source,clojure]
119+
----
120+
(derive ::sub-custom-error-type ::custom-error-type)
121+
;; => nil
122+
123+
(custom-error? (merr/error {:type ::sub-custom-error-type}))
124+
;; => true
94125
----
95126

96127
== Integration

bb_test_runner.clj

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
(ns bb-test-runner
22
(:require
33
[clojure.test :as t]
4-
[merr.core-test]))
4+
[merr.core-test]
5+
[merr.helper-test]))
56

67
(t/run-tests 'merr.core-test)
8+
(t/run-tests 'merr.helper-test)

deps.edn

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{:dev
66
{:extra-paths ["dev" "test"]
77
:extra-deps {lambdaisland/kaocha {:mvn/version "1.71.1119"}
8-
com.github.liquidz/testdoc {:mvn/version "1.5.106"}
8+
com.github.liquidz/testdoc {:mvn/version "1.5.109"}
99
orchestra/orchestra {:mvn/version "2021.01.01-1"}}}
1010

1111
:1.9

src/merr/core.cljc

+40-32
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,35 @@
99
(defrecord MerrError
1010
[type message data cause])
1111

12-
(defn err?
12+
(defn error?
1313
"Returns `true` if x is `MerrError`.
1414
1515
```
16-
=> (err? \"foo\")
16+
=> (error? \"foo\")
1717
false
1818
19-
=> (err? (err {:message \"foo\"}))
19+
=> (error? (error {:message \"foo\"}))
2020
true
2121
```"
2222
[x]
2323
(instance? MerrError x))
2424

25-
(defn err
25+
(defn error
2626
"Returns value as `MerrError`.
2727
2828
**NOTE** Default error type is `:error`
2929
3030
```
31-
=> (:type (err {:message \"hello\"}))
31+
=> (:type (error {:message \"hello\"}))
3232
:error
3333
34-
=> (:type (err {:type :custom-error :message \"hello\"}))
34+
=> (:type (error {:type :custom-error :message \"hello\"}))
3535
:custom-error
3636
37-
=> (:data (err {:data {:foo \"bar\"}}))
37+
=> (:data (error {:data {:foo \"bar\"}}))
3838
{:foo \"bar\"}
3939
```"
40-
([] (err {}))
40+
([] (error {}))
4141
([{:keys [type message data cause]
4242
:or {type default-error-type} :as m}]
4343
(clojure.core/-> m
@@ -53,7 +53,7 @@
5353
(if (some #(% v) ignore-checkers)
5454
[v nil]
5555
`(clojure.core/let [v# ~v]
56-
(if (err? v#) [nil v#] [v# nil]))))
56+
(if (error? v#) [nil v#] [v# nil]))))
5757

5858
(defmacro let
5959
"binding => binding-form init-expr
@@ -64,12 +64,12 @@
6464
```
6565
=> (let +err+ [a 1
6666
=> b (inc a)]
67-
=> [a b (err? +err+)])
67+
=> [a b (error? +err+)])
6868
[1 2 false]
6969
70-
=> (let +err+ [a (err {:message \"ERR\"})
70+
=> (let +err+ [a (error {:message \"ERR\"})
7171
=> b (inc a)]
72-
=> [a b (err? +err+)])
72+
=> [a b (error? +err+)])
7373
[nil nil true]
7474
```"
7575
{:style/indent 2}
@@ -93,41 +93,41 @@
9393
"Get error type.
9494
9595
```
96-
=> (type (err {:type :foo :message \"bar\"}))
96+
=> (type (error {:type :foo :message \"bar\"}))
9797
:foo
9898
```"
9999
[e]
100-
(when (err? e) (:type e)))
100+
(when (error? e) (:type e)))
101101

102102
(defn message
103103
"Get error message.
104104
105105
```
106-
=> (message (err {:type :foo :message \"bar\"}))
106+
=> (message (error {:type :foo :message \"bar\"}))
107107
\"bar\"
108108
```"
109109
[e]
110-
(when (err? e) (:message e)))
110+
(when (error? e) (:message e)))
111111

112112
(defn data
113113
"Get error custom data.
114114
115115
```
116-
=> (data (err {:message \"bar\" :data {:hello \"world\"}}))
116+
=> (data (error {:message \"bar\" :data {:hello \"world\"}}))
117117
{:hello \"world\"}
118118
```"
119119
[e]
120-
(when (err? e) (:data e)))
120+
(when (error? e) (:data e)))
121121

122122
(defn cause
123123
"Get error cause.
124124
125125
```
126-
=> (cause (err {:message \"foo\" :cause (err {:message \"bar\"})}))
127-
(err {:message \"bar\"})
126+
=> (cause (error {:message \"foo\" :cause (error {:message \"bar\"})}))
127+
(error {:message \"bar\"})
128128
```"
129129
[e]
130-
(when (err? e) (:cause e)))
130+
(when (error? e) (:cause e)))
131131

132132
(defmacro ->
133133
"Threads the expr through the forms. Inserts x as the
@@ -181,23 +181,23 @@
181181

182182
(defn- ex->err
183183
[cljs? ex & [m]]
184-
`(err {:type (or (:type ~m)
185-
(:merr/type (ex-data ~ex))
186-
default-error-type)
187-
:message (or (:message ~m)
188-
(if ~cljs?
189-
(.-message ~ex)
190-
(.getMessage ~ex)))
191-
:data (merge (:data ~m)
192-
(ex-data ~ex))
193-
:cause ~ex}))
184+
`(error {:type (or (:type ~m)
185+
(:merr/type (ex-data ~ex))
186+
default-error-type)
187+
:message (or (:message ~m)
188+
(if ~cljs?
189+
(.-message ~ex)
190+
(.getMessage ~ex)))
191+
:data (merge (:data ~m)
192+
(ex-data ~ex))
193+
:cause ~ex}))
194194

195195
#?(:clj (defmacro try
196196
"Returs `MerrError` when Exceptions/Errors are thrown.
197197
198198
```
199199
=> (merr.core/try (throw (ex-info \"hello\" {})))
200-
err?
200+
error?
201201
202202
=> (type (merr.core/try {:type :test} (throw (ex-info \"hello\" {}))))
203203
:test
@@ -235,3 +235,11 @@
235235
~@body
236236
(catch js/Error ~ex-sym
237237
~(ex->err true ex-sym m))))))
238+
239+
(def ^:deprecated err?
240+
"DEPRECATED"
241+
error?)
242+
243+
(def ^:deprecated err
244+
"DEPRECATED"
245+
error)

src/merr/helper.cljc

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
(ns merr.helper
2+
(:require
3+
[merr.core :as core]))
4+
5+
(defn typed-error
6+
"Returns type specified `merr.core.MerrError`
7+
8+
```
9+
=> (def custom-error (partial typed-error ::custom))
10+
var?
11+
12+
=> (:type (custom-error))
13+
::custom
14+
15+
=> (:message (custom-error {:message \"hello\"}))
16+
\"hello\"
17+
```"
18+
([error-type]
19+
(typed-error error-type {}))
20+
([error-type {:as m :keys [message data cause]}]
21+
(core/error (assoc m :type error-type))))
22+
23+
(defn typed-error?
24+
"Returns `true` if x is type specified `merr.core.MerrError`
25+
26+
```
27+
=> (def custom-error? (partial typed-error? ::custom))
28+
var?
29+
30+
=> (custom-error? (merr.core/error {:type ::custom}))
31+
true
32+
33+
=> (custom-error? (merr.core/error {:type ::another}))
34+
false
35+
36+
=> (derive ::derived ::custom)
37+
nil
38+
39+
=> (custom-error? (merr.core/error {:type ::derived}))
40+
true
41+
```
42+
"
43+
[error-type err]
44+
(boolean
45+
(some-> (core/type err)
46+
(isa? error-type))))

0 commit comments

Comments
 (0)