Add ability to map raise errorcode/message to http status
This commit is contained in:
committed by
Steve Chávez
parent
d9a250d2cb
commit
38de56de4a
@@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- #887, #601, Allow specifying dictionary and plain/phrase tsquery in full text search - @steve-chavez
|
||||
- #328, Allow doing GET on rpc - @steve-chavez
|
||||
- #917, Add ability to map RAISE errorcode/message to http status - @steve-chavez
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
+14
-6
@@ -22,6 +22,7 @@ import Network.HTTP.Types.Header
|
||||
import qualified Network.HTTP.Types.Status as HT
|
||||
import Network.Wai (Response, responseLBS)
|
||||
import PostgREST.Types
|
||||
import Text.Read (readMaybe)
|
||||
|
||||
apiRequestError :: ApiRequestError -> Response
|
||||
apiRequestError err =
|
||||
@@ -109,11 +110,17 @@ instance JSON.ToJSON P.UsageError where
|
||||
toJSON (P.SessionError e) = JSON.toJSON e -- H.Error
|
||||
|
||||
instance JSON.ToJSON H.Error where
|
||||
toJSON (H.ResultError (H.ServerError c m d h)) = JSON.object [
|
||||
"code" .= (toS c::Text),
|
||||
"message" .= (toS m::Text),
|
||||
"details" .= (fmap toS d::Maybe Text),
|
||||
"hint" .= (fmap toS h::Maybe Text)]
|
||||
toJSON (H.ResultError (H.ServerError c m d h)) = case toS c of
|
||||
'P':'T':_ ->
|
||||
JSON.object [
|
||||
"details" .= (fmap toS d::Maybe Text),
|
||||
"hint" .= (fmap toS h::Maybe Text)]
|
||||
_ ->
|
||||
JSON.object [
|
||||
"code" .= (toS c::Text),
|
||||
"message" .= (toS m::Text),
|
||||
"details" .= (fmap toS d::Maybe Text),
|
||||
"hint" .= (fmap toS h::Maybe Text)]
|
||||
toJSON (H.ResultError (H.UnexpectedResult m)) = JSON.object [
|
||||
"message" .= (m::Text)]
|
||||
toJSON (H.ResultError (H.RowError i H.EndOfInput)) = JSON.object [
|
||||
@@ -138,7 +145,7 @@ instance JSON.ToJSON H.Error where
|
||||
|
||||
httpStatus :: Bool -> P.UsageError -> HT.Status
|
||||
httpStatus _ (P.ConnectionError _) = HT.status503
|
||||
httpStatus authed (P.SessionError (H.ResultError (H.ServerError c _ _ _))) =
|
||||
httpStatus authed (P.SessionError (H.ResultError (H.ServerError c m _ _))) =
|
||||
case toS c of
|
||||
'0':'8':_ -> HT.status503 -- pg connection err
|
||||
'0':'9':_ -> HT.status500 -- triggered action exception
|
||||
@@ -166,6 +173,7 @@ httpStatus authed (P.SessionError (H.ResultError (H.ServerError c _ _ _))) =
|
||||
"42883" -> HT.status404 -- undefined function
|
||||
"42P01" -> HT.status404 -- undefined table
|
||||
"42501" -> if authed then HT.status403 else HT.status401 -- insufficient privilege
|
||||
'P':'T':n -> fromMaybe HT.status500 (HT.mkStatus <$> readMaybe n <*> pure m)
|
||||
_ -> HT.status400
|
||||
httpStatus _ (P.SessionError (H.ResultError _)) = HT.status500
|
||||
httpStatus _ (P.SessionError (H.ClientError _)) = HT.status503
|
||||
|
||||
@@ -276,6 +276,16 @@ spec =
|
||||
get "/rpc/many_inout_params?num=1&str=two" `shouldRespondWith`
|
||||
[json| [{"num":1,"str":"two","b":true}]|] { matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "can map a RAISE error code and message to a http status" $
|
||||
get "/rpc/raise_pt402"
|
||||
`shouldRespondWith` [json|{ "hint": "Upgrade your plan", "details": "Quota exceeded" }|]
|
||||
{ matchStatus = 402
|
||||
, matchHeaders = [matchContentTypeJson]
|
||||
}
|
||||
|
||||
it "defaults to status 500 if RAISE code is PT not followed by a number" $
|
||||
get "/rpc/raise_bad_pt" `shouldRespondWith` 500
|
||||
|
||||
context "only for POST rpc" $ do
|
||||
context "expects a single json object" $ do
|
||||
it "does not expand posted json into parameters" $
|
||||
|
||||
Vendored
+14
@@ -1292,6 +1292,20 @@ $$ language sql;
|
||||
create function test.many_inout_params(INOUT num int, INOUT str text, INOUT b bool DEFAULT true) AS $$
|
||||
select num, str, b;
|
||||
$$ language sql;
|
||||
|
||||
create or replace function test.raise_pt402() returns void as $$
|
||||
begin
|
||||
raise sqlstate 'PT402' using message = 'Payment Required',
|
||||
detail = 'Quota exceeded',
|
||||
hint = 'Upgrade your plan';
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create or replace function test.raise_bad_pt() returns void as $$
|
||||
begin
|
||||
raise sqlstate 'PT40A' using message = 'Wrong';
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
Reference in New Issue
Block a user