catch clojure exceptions hook, line, and sinker
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Clojure 91.1%
Other 8.9%
10 1 0

Clone this repository

https://tangled.org/noahbogart.com/sinker https://tangled.org/did:plc:qbidoe2gpkfelnurqod37ikr/sinker
git@knot.noahbogart.com:noahbogart.com/sinker git@knot.noahbogart.com:did:plc:qbidoe2gpkfelnurqod37ikr/sinker

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

noahtheduke/sinker#

catch exceptions hook, line, and sinker.

installation#

:deps {io.github.noahtheduke/sinker {:mvn/version "0.1.0"}}

features#

it's try but a little nicer:

(require '[noahtheduke.sinker :refer [try+]])

;; works like normal try
(try+ 1 2 3)
;; => 3

(try+ (throw (Exception. "hello world!"))
  (catch Exception ex
    (ex-message ex)))
;; => "hello world!"

;; ex-infos with `:type` ex-data can be caught with a keyword.
;; the keywords are compared with isa? to respect heirarchies.
;; the bound variable is the ex-data, not the exception itself.
(try+ (throw (ex-info "Wrong parameter" {:type :invalid-parameter
                                         :expected :abc
                                         :given :foobar}))
  (catch :invalid-parameter data
    (:given data)))
;; => :foobar

;; the exception is on the metadata of the bind under the key `:noahtheduke.sinker/exception`.
(try+ (throw (ex-info "Wrong parameter" {:type :invalid-parameter
                                         :expected 'abc
                                         :given 'foobar}))
  (catch :invalid-parameter data
    (ex-message (:noahtheduke.sinker/exception (meta data)))))
;; => "Wrong parameter"

;; because the ex-data is a map, it can be destructured
(try+ (throw (ex-info "Wrong parameter" {:type :invalid-parameter
                                         :expected :abc
                                         :given :foobar}))
  (catch :invalid-parameter {:keys [expected given]}
    [expected given (= expected given)]))
;; => [:abc :foobar false]

;; ex-infos can also be caught with predicate functions or vars.
;; the predicate must be a 1-arg function that takes the `ex-data`.
;; like catching a keyword, the bound variable is the ex-data, not the exception itself.
(defn pred [data]
  (= :value (:key data)))

(try+ (throw (ex-info "KV pair" {:type :incorrect-argument
                                 :key :value}))
  (catch pred data
    (:key data)))
;; => :value

;; like normal try, each catch is checked in definition order,
;; and finally clauses gotta come last
(defn pred2 [data]
  (= :value2 (:key2 data)))
(def errored? (atom nil))

(try+ (assert (= 1 2) "This will work")
  (catch :invalid-argument _
    :invalid-argument)
  (catch pred2 ex
    (ex-message ex))
  (catch clojure.lang.ExceptionInfo ex
    (ex-data ex))
  (catch Exception _
    "Got us an exception!")
  (catch Throwable t
    (str "Received a " (.getName (class t))))
  (finally
    (reset! errored? "hoodee hoodee hoo")))
;; => "Received a java.lang.AssertionError"

@errored?
;; => "hoodee hoodee hoo"

license#

Copyright © Noah Bogart

Distributed under the Mozilla Public License version 2.0.