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
|
- #887, #601, Allow specifying dictionary and plain/phrase tsquery in full text search - @steve-chavez
|
||||||
- #328, Allow doing GET on rpc - @steve-chavez
|
- #328, Allow doing GET on rpc - @steve-chavez
|
||||||
|
- #917, Add ability to map RAISE errorcode/message to http status - @steve-chavez
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
+14
-6
@@ -22,6 +22,7 @@ import Network.HTTP.Types.Header
|
|||||||
import qualified Network.HTTP.Types.Status as HT
|
import qualified Network.HTTP.Types.Status as HT
|
||||||
import Network.Wai (Response, responseLBS)
|
import Network.Wai (Response, responseLBS)
|
||||||
import PostgREST.Types
|
import PostgREST.Types
|
||||||
|
import Text.Read (readMaybe)
|
||||||
|
|
||||||
apiRequestError :: ApiRequestError -> Response
|
apiRequestError :: ApiRequestError -> Response
|
||||||
apiRequestError err =
|
apiRequestError err =
|
||||||
@@ -109,11 +110,17 @@ instance JSON.ToJSON P.UsageError where
|
|||||||
toJSON (P.SessionError e) = JSON.toJSON e -- H.Error
|
toJSON (P.SessionError e) = JSON.toJSON e -- H.Error
|
||||||
|
|
||||||
instance JSON.ToJSON H.Error where
|
instance JSON.ToJSON H.Error where
|
||||||
toJSON (H.ResultError (H.ServerError c m d h)) = JSON.object [
|
toJSON (H.ResultError (H.ServerError c m d h)) = case toS c of
|
||||||
"code" .= (toS c::Text),
|
'P':'T':_ ->
|
||||||
"message" .= (toS m::Text),
|
JSON.object [
|
||||||
"details" .= (fmap toS d::Maybe Text),
|
"details" .= (fmap toS d::Maybe Text),
|
||||||
"hint" .= (fmap toS h::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 [
|
toJSON (H.ResultError (H.UnexpectedResult m)) = JSON.object [
|
||||||
"message" .= (m::Text)]
|
"message" .= (m::Text)]
|
||||||
toJSON (H.ResultError (H.RowError i H.EndOfInput)) = JSON.object [
|
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 :: Bool -> P.UsageError -> HT.Status
|
||||||
httpStatus _ (P.ConnectionError _) = HT.status503
|
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
|
case toS c of
|
||||||
'0':'8':_ -> HT.status503 -- pg connection err
|
'0':'8':_ -> HT.status503 -- pg connection err
|
||||||
'0':'9':_ -> HT.status500 -- triggered action exception
|
'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
|
"42883" -> HT.status404 -- undefined function
|
||||||
"42P01" -> HT.status404 -- undefined table
|
"42P01" -> HT.status404 -- undefined table
|
||||||
"42501" -> if authed then HT.status403 else HT.status401 -- insufficient privilege
|
"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
|
_ -> HT.status400
|
||||||
httpStatus _ (P.SessionError (H.ResultError _)) = HT.status500
|
httpStatus _ (P.SessionError (H.ResultError _)) = HT.status500
|
||||||
httpStatus _ (P.SessionError (H.ClientError _)) = HT.status503
|
httpStatus _ (P.SessionError (H.ClientError _)) = HT.status503
|
||||||
|
|||||||
@@ -276,6 +276,16 @@ spec =
|
|||||||
get "/rpc/many_inout_params?num=1&str=two" `shouldRespondWith`
|
get "/rpc/many_inout_params?num=1&str=two" `shouldRespondWith`
|
||||||
[json| [{"num":1,"str":"two","b":true}]|] { matchHeaders = [matchContentTypeJson] }
|
[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 "only for POST rpc" $ do
|
||||||
context "expects a single json object" $ do
|
context "expects a single json object" $ do
|
||||||
it "does not expand posted json into parameters" $
|
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 $$
|
create function test.many_inout_params(INOUT num int, INOUT str text, INOUT b bool DEFAULT true) AS $$
|
||||||
select num, str, b;
|
select num, str, b;
|
||||||
$$ language sql;
|
$$ 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
|
-- PostgreSQL database dump complete
|
||||||
--
|
--
|
||||||
|
|||||||
Reference in New Issue
Block a user