cdepillabout / cdepillabout/servant-checked-exceptions

add note about having to be careful with letting aeson derive FromJSON and ToJSON instances

Open
#14 0 comments 1 reaction 0 assignees View on GitHub
help wanted
Dominant language
Haskell
Stars
75
Forks
14
PR merge metrics
No merged PRs in 30d

Description

By default, Aeson may derive instances for error types that cannot be differentiated from one another.

For example, given the following code:

```haskell
data FooErr = FooErr deriving (Eq, Read, Show)

$(deriveJSON defaultOptions ''FooErr)

data BarErr = BarErr deriving (Eq, Read, Show)

$(deriveJSON defaultOptions ''BarErr)
```

`deriveJSON` will derive instances that work like the following:

```haskell
> encode (toErrEnvelope FooErr :: Envelope '[FooErr] Int)
"{\"err\":[]}"
> encode (toErrEnvelope BarErr :: Envelope '[BarErr] Int)
"{\"err\":[]}"
```

Just by looking at the output JSON, it is not possible to tell whether the error was originally a `FooErr` or a `BarErr`.

It is necessary to write the `ToJSON` and `FromJSON` instances by hand like the following:

```haskell
data FooErr = FooErr deriving (Eq, Read, Show)

instance FromJSON FooErr where
parseJSON = withText "FooErr" $ \case
"FooErr" -> pure FooErr
other ->
fail $ "Trying to parse FooErr, but got \"" <> unpack other <> "\""

instance ToJSON FooErr where { toJSON _ = String "FooErr" }

data BarErr = BarErr deriving (Eq, Read, Show)

instance FromJSON BarErr where
parseJSON = withText "BarErr" $ \case
"BarErr" -> pure BarErr
other ->
fail $ "Trying to parse BarErr, but got \"" <> unpack other <> "\""

instance ToJSON BarErr where { toJSON _ = String "BarErr" }
```

This lets the `FromJSON` and `ToJSON` instance for `Envelope` work correctly:

```haskell
> encode (toErrEnvelope FooErr :: Envelope '[FooErr ] Int)
"{\"err\":\"FooErr\"}"
> encode (toErrEnvelope BarErr :: Envelope '[BarErr ] Int)
"{\"err\":\"BarErr\"}"
```

It would be nice to add a note warning about this somewhere in this package. Probably on the `ToJSON` and `FromJSON` instances for `Envelope`.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.