Provide detailed logging for any db errors caused internally by postgrest

This commit is contained in:
Joe Nelson
2015-10-12 17:10:52 -07:00
parent 2373a41699
commit e37b2d8c59
2 changed files with 22 additions and 17 deletions
+1
View File
@@ -37,6 +37,7 @@ executable postgrest
, case-insensitive , case-insensitive
, scientific, time , scientific, time
, aeson >= 0.8, network >= 2.6 , aeson >= 0.8, network >= 2.6
, aeson-pretty >= 0.7 && < 0.8
, bytestring, text, split, string-conversions , bytestring, text, split, string-conversions
, stringsearch , stringsearch
, containers, unordered-containers , containers, unordered-containers
+21 -17
View File
@@ -1,39 +1,41 @@
module Main where module Main where
import PostgREST.App
import PostgREST.Config (AppConfig (..),
minimumPgVersion,
prettyVersion,
readOptions)
import PostgREST.Error (errResponse, PgError)
import PostgREST.Middleware
import PostgREST.PgStructure import PostgREST.PgStructure
import PostgREST.Types import PostgREST.Types
import Network.Wai
import PostgREST.App
import PostgREST.Error (errResponse)
import PostgREST.Middleware
import Control.Monad (unless) import Control.Monad (unless)
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
import Data.Aeson.Encode.Pretty (encodePretty)
import Data.Functor.Identity import Data.Functor.Identity
import Data.Monoid ((<>)) import Data.Monoid ((<>))
import Data.String.Conversions (cs) import Data.String.Conversions (cs)
import Data.Text (Text) import Data.Text (Text)
import qualified Hasql as H import qualified Hasql as H
import qualified Hasql.Postgres as P import qualified Hasql.Postgres as P
import Network.Wai
import Network.Wai.Handler.Warp hiding (Connection) import Network.Wai.Handler.Warp hiding (Connection)
import Network.Wai.Middleware.RequestLogger (logStdout) import Network.Wai.Middleware.RequestLogger (logStdout)
import System.IO (BufferMode (..), import System.IO (BufferMode (..),
hSetBuffering, stderr, hSetBuffering, stderr,
stdin, stdout) stdin, stdout)
import PostgREST.Config (AppConfig (..),
prettyVersion,
readOptions,
minimumPgVersion)
isServerVersionSupported :: H.Session P.Postgres IO Bool isServerVersionSupported :: H.Session P.Postgres IO Bool
isServerVersionSupported = do isServerVersionSupported = do
Identity (row :: Text) <- H.tx Nothing $ H.singleEx [H.stmt|SHOW server_version_num|] Identity (row :: Text) <- H.tx Nothing $ H.singleEx [H.stmt|SHOW server_version_num|]
return $ read (cs row) >= minimumPgVersion return $ read (cs row) >= minimumPgVersion
hasqlError :: PgError -> IO a
hasqlError = error . cs . encodePretty
main :: IO () main :: IO ()
main = do main = do
hSetBuffering stdout LineBuffering hSetBuffering stdout LineBuffering
@@ -61,15 +63,17 @@ main = do
pool :: H.Pool P.Postgres <- H.acquirePool pgSettings poolSettings pool :: H.Pool P.Postgres <- H.acquirePool pgSettings poolSettings
supportedOrError <- H.session pool isServerVersionSupported supportedOrError <- H.session pool isServerVersionSupported
either (fail . show) either hasqlError
(\supported -> (\supported ->
unless supported $ unless supported $
fail "Cannot run in this PostgreSQL version, PostgREST needs at least 9.2.0" error "Cannot run in this PostgreSQL version, PostgREST needs at least 9.2.0"
) supportedOrError ) supportedOrError
Right authenticator <- H.session pool $ do roleOrError <- H.session pool $ do
Identity (role :: Text) <- H.tx Nothing $ H.singleEx [H.stmt|SELECT SESSION_USER|] Identity (role :: Text) <- H.tx Nothing $ H.singleEx
[H.stmt|SELECT SESSION_USER|]
return role return role
authenticator <- either hasqlError return roleOrError
let txSettings = Just (H.ReadCommitted, Just True) let txSettings = Just (H.ReadCommitted, Just True)
metadata <- H.session pool $ H.tx txSettings $ do metadata <- H.session pool $ H.tx txSettings $ do
@@ -79,15 +83,15 @@ main = do
keys <- allPrimaryKeys keys <- allPrimaryKeys
return (tabs, rels, cols, keys) return (tabs, rels, cols, keys)
dbstructure <- case metadata of dbstructure <- either hasqlError
Left e -> fail $ show e (\(tabs, rels, cols, keys) ->
Right (tabs, rels, cols, keys) ->
return DbStructure { return DbStructure {
tables=tabs tables=tabs
, columns=cols , columns=cols
, relations=rels , relations=rels
, primaryKeys=keys , primaryKeys=keys
} }
) metadata
runSettings appSettings $ middle $ \ req respond -> do runSettings appSettings $ middle $ \ req respond -> do
body <- strictRequestBody req body <- strictRequestBody req