Product Promotion
0x5a.live
for different kinds of informations and explorations.
GitHub - mpenet/ex: Exception net
Exception net. Contribute to mpenet/ex development by creating an account on GitHub.
Visit SiteGitHub - mpenet/ex: Exception net
Exception net. Contribute to mpenet/ex development by creating an account on GitHub.
Powered by 0x5a.live ๐
ex
Deprecation notice
No longer in developement, if you want the same ideas with way better implementation, head to exoscale/ex
An exception library, drop in replacement for try
/catch
/finally
,
that adds support for ex-info
/ex-data
with a custom (clojure)
hierarchy that allows to express exceptions relations.
So we have qbits.ex/try+
, which supports vanilla catch
/finally
clauses.
If you specify a catch-data
clause with a keyword as first argument
things get interesting. We assume you always put a :type
key in the
ex-info you want to use with this, and will match its value to the
value of the key in the catch-data
clause.
Essentially catch-data
takes this form:
(catch-data :something m
;; where m is a binding to the ex-data (you can destructure at that level as well)
)
So you can do things like that.
(require '[qbits.ex :as ex])
(ex/try+
(throw (ex-info "Argh" {:type ::bar :foo "a foo"}))
(catch-data ::foo data
(prn :got-ex-data data))
(catch-data ::bar {:as data :keys [foo]}
;; in that case it would hit this one
(prn :got-ex-data-again foo))
(catch ExceptionInfo e
;; this would match an ex-info that didn't get a hit with catch-ex-info)
(catch Exception e (prn :boring))
(finally (prn :boring-too)))
But there's a twist.
I thought leveraging a clojure hierarchy could make sense in that context too, so you can essentially create exceptions hierachies without having to mess with Java classes directly and in a clojuresque" way.
;; so bar is a foo
(ex/derive ::bar ::foo)
(ex/try+
(throw (ex-info "I am a bar" {:type ::bar})
(catch-data ::foo d
(prn "got a foo with data" d)
(prn "Original exception instance is " (-> d meta ::ex/exception))))
You can also get the full exception instance via the metadata on the
ex-data we extract, it's under the :qbits.ex/exception
key.
Some real life examples of usage for this:
-
make some exceptions end-user exposable in http responses via an error middleware in a declarative way .
-
skip sentry logging for some kind of exceptions (or the inverse)
-
make an exception hierachy for our query language type of errors for specialized reporting per "type"
Other than that it's largely inspired by
catch-data, the
implementation is slightly different, we dont catch Throwable, we
instead generate a catch clause on clj ex-info
and generate a cond
that tries to match ex-data with the :type key using isa?
with our
hierarchy, which arguably is closer to I would write by hand in that
case.
Installation
ex is available on Clojars.
Add this to your dependencies:
or you can just grab it via deps.edn
directly
License
Copyright ยฉ 2018 Max Penet
Distributed under the Eclipse Public License, the same as Clojure.
Made with โค๏ธ
to provide different kinds of informations and resources.