Skip to content

Commit

Permalink
Merge pull request #15 from ford-prefect/custom-error
Browse files Browse the repository at this point in the history
Add a toAff' for native code that does not fail with Errors or strings
  • Loading branch information
nwolverson authored Apr 8, 2019
2 parents 72a6fb2 + d7a3505 commit 033d6b9
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
12 changes: 9 additions & 3 deletions src/Control/Promise.purs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Control.Promise (fromAff, toAff, toAffE, Promise()) where
module Control.Promise (fromAff, toAff, toAff', toAffE, Promise()) where

import Prelude

Expand Down Expand Up @@ -37,10 +37,16 @@ coerce fn =
-- | coerce the error value into an actual JavaScript Error object. We can do this
-- | with Error objects or Strings. Anything else gets a "dummy" Error object.
toAff :: forall a. Promise a -> Aff a
toAff p = makeAff
toAff = toAff' coerce

-- | Convert a Promise into an Aff with custom Error coercion.
-- | When the promise rejects, we attempt to coerce the error value into an
-- | actual JavaScript Error object using the provided function.
toAff' :: forall a. (Foreign -> Error) -> Promise a -> Aff a
toAff' customCoerce p = makeAff
(\cb -> mempty <$ thenImpl
p
(mkEffectFn1 $ cb <<< Left <<< coerce)
(mkEffectFn1 $ cb <<< Left <<< customCoerce)
(mkEffectFn1 $ cb <<< Right))

-- | Utility to convert an Effect returning a Promise into an Aff (i.e. the inverse of fromAff)
Expand Down
1 change: 1 addition & 0 deletions test/Main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
exports.helloPromise = Promise.resolve("Hello");
exports.goodbyePromise = Promise.reject("Goodbye");
exports.errPromise = Promise.reject(new Error('err'));
exports.customErrPromise = Promise.reject({ code: "err" });
14 changes: 12 additions & 2 deletions test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ module Test.Main where

import Prelude

import Control.Monad.Except (throwError)
import Control.Monad.Except (runExcept, throwError)
import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Either (either)
import Effect (Effect)
import Effect.Aff (attempt)
import Effect.Class (liftEffect)
import Effect.Exception (message, error)
import Effect.Exception (error, message)
import Foreign (readString, unsafeFromForeign)
import Foreign.Index (readProp)
import Test.Unit (suite, test, timeout)
import Test.Unit.Assert as Assert
import Test.Unit.Main (runTest)
Expand All @@ -18,6 +20,8 @@ foreign import helloPromise :: Promise String

foreign import errPromise :: Promise String

foreign import customErrPromise :: Promise String

foreign import goodbyePromise :: Promise String

main :: Effect Unit
Expand All @@ -29,6 +33,9 @@ main = runTest do
test "err" do
res <- attempt $ Promise.toAff errPromise
Assert.equal "err" $ either message (const "-") res
test "customErr" do
res <- attempt $ Promise.toAff' errorCodeCoerce customErrPromise
Assert.equal "err" $ either message (const "-") res
test "Goodbye" do
res <- attempt $ Promise.toAff goodbyePromise
Assert.equal "Goodbye" $ either message (const "-") res
Expand All @@ -46,3 +53,6 @@ main = runTest do
promise <- liftEffect $ Promise.fromAff $ throwError $ error "err123"
res <- attempt $ Promise.toAff promise
Assert.equal "err123" $ either message (const "-") res
where
errorCodeCoerce v = either (\_ -> error "fail") error $
(runExcept $ readProp "code" (unsafeFromForeign v) >>= readString)

0 comments on commit 033d6b9

Please sign in to comment.