Skip to content

Commit baabc41

Browse files
authored
Introduce toResult to lift task errors into a Result (#37)
1 parent 697b65b commit baabc41

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

src/ConcurrentTask.elm

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module ConcurrentTask exposing
55
, onResponseDecoderFailure, onJsException
66
, mapError, onError
77
, succeed, fail, andThen
8-
, fromResult, andThenDo, return, debug
8+
, fromResult, toResult, andThenDo, return, debug
99
, batch, sequence
1010
, map, andMap, map2, map3, map4, map5
1111
, attempt, attemptEach, Response(..), UnexpectedError(..), onProgress, Pool, pool
@@ -68,7 +68,7 @@ Lift `UnexpectedError`s into regular task flow.
6868
6969
These are some general helpers that can make chaining, combining and debugging tasks more convenient.
7070
71-
@docs fromResult, andThenDo, return, debug
71+
@docs fromResult, toResult, andThenDo, return, debug
7272
7373
7474
# Batch Helpers
@@ -621,6 +621,56 @@ fromResult =
621621
Internal.fromResult
622622

623623

624+
{-| Lift a failed task into a successful one reporting the error with a `Result` type.
625+
626+
The main use case for this function is to get more localised errors.
627+
Typically, your `Msg` type will only contain a single pair of `OnProgress` and `OnComplete` variants.
628+
629+
type Msg
630+
= ...
631+
| OnProgress ( ConcurrentTask.Pool Msg, Cmd Msg )
632+
| OnComplete (ConcurrentTask.Response TaskError TaskCompleted)
633+
634+
type TaskCompleted
635+
= GotThingOne ThingOne
636+
| GotThingTwo ThingTwo
637+
638+
In the above situation, you would handle all errors in the same branch of your update function:
639+
640+
case response of
641+
ConcurrentTask.Error error -> ... -- handle all errors
642+
ConcurrentTask.Success ... -> ... -- handle successes
643+
644+
However, if instead of running `myTask`, you run `ConcurrentTask.toResult myTask`
645+
and adjust your `TaskCompleted` type to handle results, you obtain errors that are local to the task.
646+
647+
type TaskCompleted
648+
= GotThingOne (Result ErrorOne ThingOne)
649+
| GotThingTwo (Result ErrorTwo ThingTwo)
650+
651+
This pattern makes it easier to handle potential failures at the same place where you would handle correct answers.
652+
It also mirrors the behavior of the elm/http library where each message variant handles its own errors.
653+
654+
-- Example from elm/http
655+
type Msg
656+
= GotBook (Result Http.Error String)
657+
| GotItems (Result Http.Error (List String))
658+
659+
-- ConcurrentTask example of handling errors lifted to a task Result.
660+
case response of
661+
ConcurrentTask.Error error -> ... -- handle non-lifted errors
662+
ConcurrentTask.Success (GotThingOne result) ->
663+
-- deal with the first task result
664+
ConcurrentTask.Success (GotThingTwo result) ->
665+
-- deal with the second task result
666+
667+
-}
668+
toResult : ConcurrentTask err a -> ConcurrentTask x (Result err a)
669+
toResult task =
670+
map Ok task
671+
|> onError (Err >> succeed)
672+
673+
624674
{-| Similar to `andThen` but ignores the successful result of the previous Task.
625675
626676
Maybe you want to save a file then log a message to the console:

0 commit comments

Comments
 (0)