Custom Error Messages in PureScript Argonaut
purescript-argonaut-codecs computes in the Either
monad putting errors in the Left
constructor. If I want to change the error message or throw it away, I can map over the Left side of Either
, throwing away the result or changing it. To illustrate how this works here are some helper functions I use when working with PureScript Argonaut.
import Prelude
import Data.Bifunctor (class Bifunctor, lmap)
import Data.Either (Left(..))
import Data.Maybe (Maybe(..))
maybeFail :: forall a b. String -> Maybe a -> Either String a
maybeFail s m = case m of
Just mm -> Right mm
Nothing -> Left s
failWith :: forall f c. (Bifunctor f) => String -> f String c -> f String c
failWith s = lmap (\a -> s)
failAppend :: forall f c. (Bifunctor f) => String -> f String c -> f String c
failAppend s = lmap (_ <> s)
failPrepend :: forall f c. (Bifunctor f) => String -> f String c -> f String c
failPrepend s = lmap (s <> _)
Then if I'm decoding an Account
type with fields "id" and "users", I can decode an Account
from Json
, and have it return the appropriate error messages if there is a problem.
instance decodeAccount :: DecodeJson Account where
decodeJson json = do
obj <- maybeFail "Account must be an object." (toObject json)
id <- failWith "Account is missing 'id' field." $ getField obj "id"
users <- (failWith "Account is missing 'users' field.") (getField obj "users")
pure $ Account {id, users}