项目作者: mpenet

项目描述 :
Exception net
高级语言: Clojure
项目地址: git://github.com/mpenet/ex.git
创建时间: 2018-07-10T13:49:23Z
项目社区:https://github.com/mpenet/ex

开源协议:

下载


ex

Deprecation notice

No longer in developement, if you want the same ideas with way better implementation, head to exoscale/ex

cljdoc badge

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:

  1. (catch-data :something m
  2. ;; where m is a binding to the ex-data (you can destructure at that level as well)
  3. )

So you can do things like that.

  1. (require '[qbits.ex :as ex])
  2. (ex/try+
  3. (throw (ex-info "Argh" {:type ::bar :foo "a foo"}))
  4. (catch-data ::foo data
  5. (prn :got-ex-data data))
  6. (catch-data ::bar {:as data :keys [foo]}
  7. ;; in that case it would hit this one
  8. (prn :got-ex-data-again foo))
  9. (catch ExceptionInfo e
  10. ;; this would match an ex-info that didn't get a hit with catch-ex-info)
  11. (catch Exception e (prn :boring))
  12. (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.

  1. ;; so bar is a foo
  2. (ex/derive ::bar ::foo)
  3. (ex/try+
  4. (throw (ex-info "I am a bar" {:type ::bar})
  5. (catch-data ::foo d
  6. (prn "got a foo with data" d)
  7. (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:

Clojars Project

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.