Skip to content

Commit

Permalink
Add attempt, prepare docs for 2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
adambard committed Dec 29, 2020
1 parent 932c211 commit 24ba4ef
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 14 deletions.
63 changes: 50 additions & 13 deletions README.markdown
Expand Up @@ -52,6 +52,19 @@ if you're into that sort of thing:

## Quick Reference

### `HasFailed`

The cornerstone of this library, `HasFailed` is the protocol that describes a failed result.
Failjure implements HasFailed for Object (the catch-all not-failed implementation), Exception, and the
built-in Failure record type, but you can add your own very easily:

```clojure
(defrecord AnnotatedFailure [message data]
f/HasFailed
(failed? [self] true)
(message [self] (:message self)))
```

### `fail`

`fail` is the basis of this library. It accepts an error message
Expand All @@ -69,6 +82,21 @@ These two functions are part of the `HasFailed` protocol underpinning
failjure. `failed?` will tell you if a value is a failure (that is,
a `Failure`, a java `Exception` or a JavaScript `Error`.

### `attempt`

_Added in 2.1_

Accepts a value and a function. If the value is a failure, it is passed
to the function and the result is returned. Otherwise, value is returned.

```clojure
(defn handle-error [e] (str "Error: " (f/message e)))
(f/attempt handle-error "Ok") ;=> "Ok"
(f/attempt handle-error (f/fail "failure")) ;=> "Error: failure"
```

Try it with `partial`!

### `attempt-all`

`attempt-all` wraps an error monad for easy use with failure-returning
Expand Down Expand Up @@ -120,6 +148,24 @@ correct this shortcoming*
(handle-failure result)))
```

### `as-ok->`

_Added in 2.1_

Like clojure's built-in `as->`, but short-circuits on failures.

```clojure

(f/as-ok-> "k" $
(str $ "!")
(str "O" $))) ; => Ok!

(f/as-ok-> "k" $
(str $ "!")
(f/try* (Integer/parseInt $))
(str "O" $))) ; => Returns (does not throw) a NumberFormatException
```

### `try*`

This library does not handle exceptions by default. However,
Expand All @@ -145,19 +191,6 @@ bindings in a `try*` is available as `try-all` (thanks @lispyclouds):
y) ; => java.lang.ArithmeticException (returned, not thrown)
```

### `HasFailed`

`HasFailed` is the protocol that describes a failed result. This library implements
HasFailed for Object (the catch-all not-failed implementation), Exception, and the
built-in Failure record type, but you can add your own very easily:

```clojure
(defrecord AnnotatedFailure [message data]
f/HasFailed
(failed? [self] true)
(message [self] (:message self)))
```

### `(if-|when-)-let-(ok?|failed?)`

Failjure provides the helpers `if-let-ok?`, `if-let-failed?`, `when-let-ok?` and `when-let-failed?` to help
Expand Down Expand Up @@ -201,6 +234,10 @@ are provided, but if you like, adding your own is as easy as `(def assert-my-pre

## Changelog

#### 2.1.0

Added `attempt` and `as-ok->`. Changed from boot to leiningen for builds.

#### 2.0.0

Added ClojureScript support. Since the jar now includes .cljc instead of .clj files, which could
Expand Down
8 changes: 8 additions & 0 deletions src/failjure/core.cljc
Expand Up @@ -54,6 +54,13 @@
([msg & fmt-parts]
(->Failure (apply format msg fmt-parts))))

(defn attempt
"Accepts a (possibly failed) value and an error-handling function"
{:added "2.1"}
[val-or-failed handle-fn]
(if (failed? val-or-failed)
(handle-fn val-or-failed)
val-or-failed))

(defn try-fn [body-fn]
(try
Expand Down Expand Up @@ -259,6 +266,7 @@

(defmacro as-ok->
"Like as-> but with ok? "
{:added "2.1"}
[expr name & forms]
`(attempt-all [~name ~expr
~@(interleave (repeat name) (butlast forms))]
Expand Down
6 changes: 5 additions & 1 deletion test/failjure/test_core.cljc
Expand Up @@ -5,6 +5,11 @@
[failjure.core :as f :include-macros true]])))

(deftest failjure-core-test
(testing "attempt"
(let [handle-error #(str "Error: " (f/message %))]
(is (= "Ok" (f/attempt handle-error "Ok")))
(is (= "Error: failed" (f/attempt handle-error (f/fail "failed"))))))

(testing "attempt-all"
(testing "basically works"
(is (= "Ok"
Expand All @@ -21,7 +26,6 @@
]
(str x y)))))


(testing "Returns the exception for try*"
(let [result (f/attempt-all [x "O"
y (f/try* #?(:clj (Integer/parseInt "k")
Expand Down

0 comments on commit 24ba4ef

Please sign in to comment.