Scotty と Persistent を使用して REST バックエンドを開発していますが、エラーを処理する正しい方法がわかりません。
次のような DB にアクセスするための関数がいくつかあります。
getItem :: Text -> SqlPersistM (Either Error Item)
SQLモナド内のいずれかを返します。次に、アクションでそれを使用してアイテムを取得し、その JSON 表現を返します。
get "/items/:name" $ do
name <- param "name"
eitherItem <- lift $ MyDB.getItem name
case eitherItem of
Left NotFound -> do
status status404
json NotFound
Left InvalidArgument -> do
status status400
json BadRequest
Right item -> json item
いくつかのヘルパーを導入することでコードをよりきれいにすることができますが、パターンは同じままです - データベースにアクセスし、エラーをチェックし、適切な応答をレンダリングします.
アクションでエラー処理を完全に取り除きたいです。
get "/items/:name" $ do
name <- param "name"
item <- lift $ MyDB.getItem name
-- In case of error, appropriate
-- HTTP response will be sent,
-- else just continue
bars <- lift $ MyDB.listBars
-- In case of error, appropriate
-- HTTP response will be sent,
-- else just continue
json (process item bars)
つまりgetItem
、エラーが返される場合があり、アクション コードに対してすべて透過的に、何らかの方法で json 応答に変換されます。getItem
アクションとjson応答について何も知らないといいですね。
私は過去に命令型言語を使用して、どこからでも例外をスローし、それを 1 か所でキャッチして適切な応答をレンダリングすることで、この問題を解決しました。Haskellでも可能だと思いますが、機能的なツールを使ってこの問題を解決する方法を知りたいです。
モナドが( のように)短絡する可能性があることは知っていEither >> Either >> Either
ますが、この少し複雑なケースでそれを使用する方法がわかりません。