Skip to content

Instantly share code, notes, and snippets.

@erewok
Last active April 28, 2017 14:51
Show Gist options
  • Save erewok/3649d2a5c5dc8b23c1093e4be92097ca to your computer and use it in GitHub Desktop.
Save erewok/3649d2a5c5dc8b23c1093e4be92097ca to your computer and use it in GitHub Desktop.
Custom Error as JSON from inside Handler
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Api.Post
(
PostApi
, postHandlers
) where
import Control.Monad.Except
import Control.Monad.IO.Class (liftIO)
import Data.Aeson
import Data.ByteString (ByteString)
import Data.Maybe
import Data.Pool (Pool, withResource)
import Data.Text (Text)
import qualified Data.Text as T
import Database.PostgreSQL.Simple
import GHC.Generics
import Network.HTTP.Types (hContentType)
import Servant
import Models.Post
type PostApi = "post" :> Capture "id" Int :> Get '[JSON] BlogPost
postHandlers :: Pool Connection -> Server PostApi
postHandlers conn = blogPostDetailH
where blogPostDetailH postId = withResource conn $ flip getPost postId
data ErrorTest = ErrorTest {status :: Text
, message :: Text} deriving (Generic)
instance ToJSON ErrorTest
missingPostBody = encode ErrorTest { status = "missing", message = "Not found"}
jsonHeader = (hContentType, "application/json")
getPost :: Connection -> Int -> Handler BlogPost
getPost conn postId = do
let q = "select * from post where id = ? and pubdate is not null"
result <- liftIO $ query conn q (Only postId)
case result of
(x:_) -> return x
[] -> throwError err404 { errBody = missingPostBody, errHeaders = [jsonHeader]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment