Merge pull request #374 from calebmer/feature/error-refactor

Small error refactor
This commit is contained in:
Joe Nelson
2015-11-16 14:50:54 -08:00
5 changed files with 26 additions and 18 deletions
+11 -8
View File
@@ -46,6 +46,11 @@ import qualified Hasql.Postgres as P
import PostgREST.Config (AppConfig (..)) import PostgREST.Config (AppConfig (..))
import PostgREST.Parsers import PostgREST.Parsers
import PostgREST.DbStructure import PostgREST.DbStructure
import PostgREST.RangeQuery
import PostgREST.Types
import PostgREST.Auth (tokenJWT)
import PostgREST.Error (errResponse)
import PostgREST.QueryBuilder ( asJson import PostgREST.QueryBuilder ( asJson
, callProc , callProc
, asCsvF , asCsvF
@@ -62,9 +67,6 @@ import PostgREST.QueryBuilder ( asJson
, countNoneF , countNoneF
, addRelations , addRelations
) )
import PostgREST.RangeQuery
import PostgREST.Types
import PostgREST.Auth (tokenJWT)
import Prelude import Prelude
@@ -86,7 +88,7 @@ app dbStructure conf reqBody req =
Left e -> return $ responseLBS status400 [jsonH] $ cs e Left e -> return $ responseLBS status400 [jsonH] $ cs e
Right (selectQuery, Nothing) -> -- should we do sanity check to make sure its a GET request? Right (selectQuery, Nothing) -> -- should we do sanity check to make sure its a GET request?
if range == Just emptyRange if range == Just emptyRange
then return $ responseLBS status416 [] "HTTP Range error" then return $ errResponse status416 "HTTP Range error"
else do else do
let q = createReadStatement selectQuery range (not $ hasPrefer "count=none") isCsv let q = createReadStatement selectQuery range (not $ hasPrefer "count=none") isCsv
row <- H.maybeEx q row <- H.maybeEx q
@@ -135,9 +137,9 @@ app dbStructure conf reqBody req =
row <- H.maybeEx q row <- H.maybeEx q
let (_, queryTotal, _, _) = extractQueryResult row let (_, queryTotal, _, _) = extractQueryResult row
return $ if queryTotal == 0 return $ if queryTotal == 0
then responseLBS status404 [] "" then notFound
else responseLBS status204 [("Content-Range", "*/"<> cs (show queryTotal))] "" else responseLBS status204 [("Content-Range", "*/"<> cs (show queryTotal))] ""
_ -> return $ responseLBS status404 [] "" _ -> return notFound
(["rpc", proc], "POST") -> do (["rpc", proc], "POST") -> do
let qi = QualifiedIdentifier schema (cs proc) let qi = QualifiedIdentifier schema (cs proc)
@@ -153,7 +155,7 @@ app dbStructure conf reqBody req =
if returnJWT if returnJWT
then "{\"token\":\"" <> cs (tokenJWT jwtSecret body) <> "\"}" then "{\"token\":\"" <> cs (tokenJWT jwtSecret body) <> "\"}"
else cs $ encode body) else cs $ encode body)
else return $ responseLBS status404 [] "" else return notFound
-- check that proc exists -- check that proc exists
-- check that arg names are all specified -- check that arg names are all specified
@@ -164,9 +166,10 @@ app dbStructure conf reqBody req =
return $ responseLBS status200 [jsonH] $ cs body return $ responseLBS status200 [jsonH] $ cs body
(_, _) -> (_, _) ->
return $ responseLBS status404 [] "" return notFound
where where
notFound = responseLBS status404 [] ""
allPrKeys = dbPrimaryKeys dbStructure allPrKeys = dbPrimaryKeys dbStructure
filterPk sc table pk = sc == (tableSchema . pkTable) pk && table == (tableName . pkTable) pk filterPk sc table pk = sc == (tableSchema . pkTable) pk && table == (tableName . pkTable) pk
path = pathInfo req path = pathInfo req
+7 -3
View File
@@ -2,13 +2,14 @@
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE TypeSynonymInstances #-}
module PostgREST.Error (PgError, errResponse) where module PostgREST.Error (PgError, pgErrResponse, errResponse) where
import Data.Aeson ((.=)) import Data.Aeson ((.=))
import qualified Data.Aeson as JSON import qualified Data.Aeson as JSON
import Data.String.Conversions (cs) import Data.String.Conversions (cs)
import Data.String.Utils (replace) import Data.String.Utils (replace)
import Data.Text (Text)
import qualified Data.Text as T import qualified Data.Text as T
import qualified Hasql as H import qualified Hasql as H
import qualified Hasql.Postgres as P import qualified Hasql.Postgres as P
@@ -18,8 +19,11 @@ import Network.Wai (Response, responseLBS)
type PgError = H.SessionError P.Postgres type PgError = H.SessionError P.Postgres
errResponse :: PgError -> Response errResponse :: HT.Status -> Text -> Response
errResponse e = responseLBS (httpStatus e) errResponse status message = responseLBS status [(hContentType, "application/json")] (cs $ T.concat ["{\"message\":\"",message,"\"}"])
pgErrResponse :: PgError -> Response
pgErrResponse e = responseLBS (httpStatus e)
[(hContentType, "application/json")] (JSON.encode e) [(hContentType, "application/json")] (JSON.encode e)
instance JSON.ToJSON PgError where instance JSON.ToJSON PgError where
+2 -2
View File
@@ -6,7 +6,7 @@ import PostgREST.Config (AppConfig (..),
minimumPgVersion, minimumPgVersion,
prettyVersion, prettyVersion,
readOptions) readOptions)
import PostgREST.Error (errResponse, PgError) import PostgREST.Error (pgErrResponse, PgError)
import PostgREST.Middleware import PostgREST.Middleware
import PostgREST.DbStructure import PostgREST.DbStructure
@@ -75,4 +75,4 @@ main = do
body <- strictRequestBody req body <- strictRequestBody req
resOrError <- liftIO $ H.session pool $ H.tx txSettings $ resOrError <- liftIO $ H.session pool $ H.tx txSettings $
runWithClaims conf (app dbStructure conf body) req runWithClaims conf (app dbStructure conf body) req
either (respond . errResponse) respond resOrError either (respond . pgErrResponse) respond resOrError
+4 -3
View File
@@ -13,7 +13,7 @@ import qualified Hasql.Postgres as P
import Network.HTTP.Types.Header (hAccept, hAuthorization) import Network.HTTP.Types.Header (hAccept, hAuthorization)
import Network.HTTP.Types.Status (status415, status400) import Network.HTTP.Types.Status (status415, status400)
import Network.Wai (Application, Request (..), Response, import Network.Wai (Application, Request (..), Response,
requestHeaders, responseLBS) requestHeaders)
import Network.Wai.Middleware.Cors (cors) import Network.Wai.Middleware.Cors (cors)
import Network.Wai.Middleware.Gzip (def, gzip) import Network.Wai.Middleware.Gzip (def, gzip)
import Network.Wai.Middleware.Static (only, staticPolicy) import Network.Wai.Middleware.Static (only, staticPolicy)
@@ -21,6 +21,7 @@ import Network.Wai.Middleware.Static (only, staticPolicy)
import PostgREST.App (contentTypeForAccept) import PostgREST.App (contentTypeForAccept)
import PostgREST.Auth (setRole, jwtClaims, claimsToSQL) import PostgREST.Auth (setRole, jwtClaims, claimsToSQL)
import PostgREST.Config (AppConfig (..), corsPolicy) import PostgREST.Config (AppConfig (..), corsPolicy)
import PostgREST.Error (errResponse)
import System.IO.Unsafe (unsafePerformIO) import System.IO.Unsafe (unsafePerformIO)
@@ -54,14 +55,14 @@ runWithClaims conf app req = do
auth = fromMaybe "" $ lookup hAuthorization hdrs auth = fromMaybe "" $ lookup hAuthorization hdrs
anon = cs $ configAnonRole conf anon = cs $ configAnonRole conf
setAnon = setRole anon setAnon = setRole anon
invalidJWT = return $ responseLBS status400 [("Content-Type","application/json")] "{\"message\":\"Invalid JWT\"}" invalidJWT = return $ errResponse status400 "Invalid JWT"
unsupportedAccept :: Application -> Application unsupportedAccept :: Application -> Application
unsupportedAccept app req respond = do unsupportedAccept app req respond = do
let let
accept = lookup hAccept $ requestHeaders req accept = lookup hAccept $ requestHeaders req
if isNothing $ contentTypeForAccept accept if isNothing $ contentTypeForAccept accept
then respond $ responseLBS status415 [] "Unsupported Accept header, try: application/json" then respond $ errResponse status415 "Unsupported Accept header, try: application/json"
else app req respond else app req respond
defaultMiddle :: Application -> Application defaultMiddle :: Application -> Application
+2 -2
View File
@@ -29,7 +29,7 @@ import qualified Data.Aeson.Types as J
import PostgREST.App (app) import PostgREST.App (app)
import PostgREST.Config (AppConfig(..)) import PostgREST.Config (AppConfig(..))
import PostgREST.Middleware import PostgREST.Middleware
import PostgREST.Error(errResponse) import PostgREST.Error(pgErrResponse)
import PostgREST.DbStructure import PostgREST.DbStructure
dbString :: String dbString :: String
@@ -61,7 +61,7 @@ withApp perform = do
body <- strictRequestBody req body <- strictRequestBody req
result <- liftIO $ H.session pool $ H.tx txSettings result <- liftIO $ H.session pool $ H.tx txSettings
$ runWithClaims cfg (app db cfg body) req $ runWithClaims cfg (app db cfg body) req
either (resp . errResponse) resp result either (resp . pgErrResponse) resp result
where middle = defaultMiddle where middle = defaultMiddle