Reorganize error groups
* Grouped Hasql errors into one error and renamed it to InternalError * Move all the General errors to ApiRequest errors
This commit is contained in:
+39
-67
@@ -98,11 +98,6 @@ instance JSON.ToJSON ApiRequestError where
|
|||||||
"message" .= message,
|
"message" .= message,
|
||||||
"details" .= details,
|
"details" .= details,
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
toJSON PutRangeNotAllowedError = JSON.object [
|
|
||||||
"code" .= GeneralErrorCode03,
|
|
||||||
"message" .= ("Range header and limit/offset querystring parameters are not allowed for PUT" :: Text),
|
|
||||||
"details" .= JSON.Null,
|
|
||||||
"hint" .= JSON.Null]
|
|
||||||
toJSON InvalidFilters = JSON.object [
|
toJSON InvalidFilters = JSON.object [
|
||||||
"code" .= ApiRequestErrorCode05,
|
"code" .= ApiRequestErrorCode05,
|
||||||
"message" .= ("Filters must include all and only primary key columns with 'eq' operators" :: Text),
|
"message" .= ("Filters must include all and only primary key columns with 'eq' operators" :: Text),
|
||||||
@@ -130,6 +125,12 @@ instance JSON.ToJSON ApiRequestError where
|
|||||||
"details" .= JSON.Null,
|
"details" .= JSON.Null,
|
||||||
"hint" .= ("Apply an 'order' using unique column(s)" :: Text)]
|
"hint" .= ("Apply an 'order' using unique column(s)" :: Text)]
|
||||||
|
|
||||||
|
toJSON PutRangeNotAllowedError = JSON.object [
|
||||||
|
"code" .= ApiRequestErrorCode14,
|
||||||
|
"message" .= ("Range header and limit/offset querystring parameters are not allowed for PUT" :: Text),
|
||||||
|
"details" .= JSON.Null,
|
||||||
|
"hint" .= JSON.Null]
|
||||||
|
|
||||||
toJSON (NoRelBetween parent child schema) = JSON.object [
|
toJSON (NoRelBetween parent child schema) = JSON.object [
|
||||||
"code" .= SchemaCacheErrorCode00,
|
"code" .= SchemaCacheErrorCode00,
|
||||||
"message" .= ("Could not find a relationship between '" <> parent <> "' and '" <> child <> "' in the schema cache" :: Text),
|
"message" .= ("Could not find a relationship between '" <> parent <> "' and '" <> child <> "' in the schema cache" :: Text),
|
||||||
@@ -222,31 +223,12 @@ instance JSON.ToJSON SQL.CommandError where
|
|||||||
"details" .= (fmap T.decodeUtf8 d :: Maybe Text),
|
"details" .= (fmap T.decodeUtf8 d :: Maybe Text),
|
||||||
"hint" .= (fmap T.decodeUtf8 h :: Maybe Text)]
|
"hint" .= (fmap T.decodeUtf8 h :: Maybe Text)]
|
||||||
|
|
||||||
toJSON (SQL.ResultError (SQL.UnexpectedResult m)) = JSON.object [
|
toJSON (SQL.ResultError resultError) = JSON.object [
|
||||||
"code" .= HasqlErrorCode00,
|
"code" .= InternalErrorCode00,
|
||||||
"message" .= (m :: Text),
|
"message" .= (show resultError :: Text),
|
||||||
"details" .= JSON.Null,
|
"details" .= JSON.Null,
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
toJSON (SQL.ResultError (SQL.RowError i SQL.EndOfInput)) = JSON.object [
|
|
||||||
"code" .= HasqlErrorCode01,
|
|
||||||
"message" .= ("Row error: end of input" :: Text),
|
|
||||||
"details" .= ("Attempt to parse more columns than there are in the result" :: Text),
|
|
||||||
"hint" .= (("Row number " <> show i) :: Text)]
|
|
||||||
toJSON (SQL.ResultError (SQL.RowError i SQL.UnexpectedNull)) = JSON.object [
|
|
||||||
"code" .= HasqlErrorCode02,
|
|
||||||
"message" .= ("Row error: unexpected null" :: Text),
|
|
||||||
"details" .= ("Attempt to parse a NULL as some value." :: Text),
|
|
||||||
"hint" .= (("Row number " <> show i) :: Text)]
|
|
||||||
toJSON (SQL.ResultError (SQL.RowError i (SQL.ValueError d))) = JSON.object [
|
|
||||||
"code" .= HasqlErrorCode03,
|
|
||||||
"message" .= ("Row error: Wrong value parser used" :: Text),
|
|
||||||
"details" .= d,
|
|
||||||
"hint" .= (("Row number " <> show i) :: Text)]
|
|
||||||
toJSON (SQL.ResultError (SQL.UnexpectedAmountOfRows i)) = JSON.object [
|
|
||||||
"code" .= HasqlErrorCode04,
|
|
||||||
"message" .= ("Unexpected amount of rows" :: Text),
|
|
||||||
"details" .= i,
|
|
||||||
"hint" .= JSON.Null]
|
|
||||||
toJSON (SQL.ClientError d) = JSON.object [
|
toJSON (SQL.ClientError d) = JSON.object [
|
||||||
"code" .= ConnectionErrorCode01,
|
"code" .= ConnectionErrorCode01,
|
||||||
"message" .= ("Database client error. Retrying the connection." :: Text),
|
"message" .= ("Database client error. Retrying the connection." :: Text),
|
||||||
@@ -381,46 +363,46 @@ instance JSON.ToJSON Error where
|
|||||||
"details" .= JSON.Null,
|
"details" .= JSON.Null,
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
|
|
||||||
|
toJSON (OffLimitsChangesError n maxs) = JSON.object [
|
||||||
|
"code" .= ApiRequestErrorCode10,
|
||||||
|
"message" .= ("The maximum number of rows allowed to change was surpassed" :: Text),
|
||||||
|
"details" .= T.unwords ["Results contain", show n, "rows changed but the maximum number allowed is", show maxs],
|
||||||
|
"hint" .= JSON.Null]
|
||||||
|
|
||||||
toJSON GucHeadersError = JSON.object [
|
toJSON GucHeadersError = JSON.object [
|
||||||
"code" .= GeneralErrorCode00,
|
"code" .= ApiRequestErrorCode11,
|
||||||
"message" .= ("response.headers guc must be a JSON array composed of objects with a single key and a string value" :: Text),
|
"message" .= ("response.headers guc must be a JSON array composed of objects with a single key and a string value" :: Text),
|
||||||
"details" .= JSON.Null,
|
"details" .= JSON.Null,
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
toJSON GucStatusError = JSON.object [
|
toJSON GucStatusError = JSON.object [
|
||||||
"code" .= GeneralErrorCode01,
|
"code" .= ApiRequestErrorCode12,
|
||||||
"message" .= ("response.status guc must be a valid status code" :: Text),
|
"message" .= ("response.status guc must be a valid status code" :: Text),
|
||||||
"details" .= JSON.Null,
|
"details" .= JSON.Null,
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
toJSON (BinaryFieldError ct) = JSON.object [
|
toJSON (BinaryFieldError ct) = JSON.object [
|
||||||
"code" .= GeneralErrorCode02,
|
"code" .= ApiRequestErrorCode13,
|
||||||
"message" .= ((T.decodeUtf8 (ContentType.toMime ct) <> " requested but more than one column was selected") :: Text),
|
"message" .= ((T.decodeUtf8 (ContentType.toMime ct) <> " requested but more than one column was selected") :: Text),
|
||||||
"details" .= JSON.Null,
|
"details" .= JSON.Null,
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
|
|
||||||
toJSON PutMatchingPkError = JSON.object [
|
toJSON PutMatchingPkError = JSON.object [
|
||||||
"code" .= GeneralErrorCode04,
|
"code" .= ApiRequestErrorCode15,
|
||||||
"message" .= ("Payload values do not match URL in primary key column(s)" :: Text),
|
"message" .= ("Payload values do not match URL in primary key column(s)" :: Text),
|
||||||
"details" .= JSON.Null,
|
"details" .= JSON.Null,
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
|
|
||||||
toJSON (SingularityError n) = JSON.object [
|
toJSON (SingularityError n) = JSON.object [
|
||||||
"code" .= GeneralErrorCode05,
|
"code" .= ApiRequestErrorCode16,
|
||||||
"message" .= ("JSON object requested, multiple (or no) rows returned" :: Text),
|
"message" .= ("JSON object requested, multiple (or no) rows returned" :: Text),
|
||||||
"details" .= T.unwords ["Results contain", show n, "rows,", T.decodeUtf8 (ContentType.toMime CTSingularJSON), "requires 1 row"],
|
"details" .= T.unwords ["Results contain", show n, "rows,", T.decodeUtf8 (ContentType.toMime CTSingularJSON), "requires 1 row"],
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
|
|
||||||
toJSON (UnsupportedVerb verb) = JSON.object [
|
toJSON (UnsupportedVerb verb) = JSON.object [
|
||||||
"code" .= GeneralErrorCode06,
|
"code" .= ApiRequestErrorCode17,
|
||||||
"message" .= ("Unsupported HTTP verb: " <> verb),
|
"message" .= ("Unsupported HTTP verb: " <> verb),
|
||||||
"details" .= JSON.Null,
|
"details" .= JSON.Null,
|
||||||
"hint" .= JSON.Null]
|
"hint" .= JSON.Null]
|
||||||
|
|
||||||
toJSON (OffLimitsChangesError n maxs) = JSON.object [
|
|
||||||
"code" .= ApiRequestErrorCode10,
|
|
||||||
"message" .= ("The maximum number of rows allowed to change was surpassed" :: Text),
|
|
||||||
"details" .= T.unwords ["Results contain", show n, "rows changed but the maximum number allowed is", show maxs],
|
|
||||||
"hint" .= JSON.Null]
|
|
||||||
|
|
||||||
toJSON NotFound = JSON.object []
|
toJSON NotFound = JSON.object []
|
||||||
toJSON (PgErr err) = JSON.toJSON err
|
toJSON (PgErr err) = JSON.toJSON err
|
||||||
toJSON (ApiRequestError err) = JSON.toJSON err
|
toJSON (ApiRequestError err) = JSON.toJSON err
|
||||||
@@ -453,6 +435,13 @@ data ErrorCode
|
|||||||
| ApiRequestErrorCode08
|
| ApiRequestErrorCode08
|
||||||
| ApiRequestErrorCode09
|
| ApiRequestErrorCode09
|
||||||
| ApiRequestErrorCode10
|
| ApiRequestErrorCode10
|
||||||
|
| ApiRequestErrorCode11
|
||||||
|
| ApiRequestErrorCode12
|
||||||
|
| ApiRequestErrorCode13
|
||||||
|
| ApiRequestErrorCode14
|
||||||
|
| ApiRequestErrorCode15
|
||||||
|
| ApiRequestErrorCode16
|
||||||
|
| ApiRequestErrorCode17
|
||||||
-- Schema Cache errors
|
-- Schema Cache errors
|
||||||
| SchemaCacheErrorCode00
|
| SchemaCacheErrorCode00
|
||||||
| SchemaCacheErrorCode01
|
| SchemaCacheErrorCode01
|
||||||
@@ -462,20 +451,8 @@ data ErrorCode
|
|||||||
| JWTErrorCode00
|
| JWTErrorCode00
|
||||||
| JWTErrorCode01
|
| JWTErrorCode01
|
||||||
| JWTErrorCode02
|
| JWTErrorCode02
|
||||||
-- Hasql library errors
|
-- Internal errors related to the Hasql library
|
||||||
| HasqlErrorCode00
|
| InternalErrorCode00
|
||||||
| HasqlErrorCode01
|
|
||||||
| HasqlErrorCode02
|
|
||||||
| HasqlErrorCode03
|
|
||||||
| HasqlErrorCode04
|
|
||||||
-- Uncategorized errors that are not related to a single module
|
|
||||||
| GeneralErrorCode00
|
|
||||||
| GeneralErrorCode01
|
|
||||||
| GeneralErrorCode02
|
|
||||||
| GeneralErrorCode03
|
|
||||||
| GeneralErrorCode04
|
|
||||||
| GeneralErrorCode05
|
|
||||||
| GeneralErrorCode06
|
|
||||||
|
|
||||||
instance JSON.ToJSON ErrorCode where
|
instance JSON.ToJSON ErrorCode where
|
||||||
toJSON e = JSON.toJSON (buildErrorCode e)
|
toJSON e = JSON.toJSON (buildErrorCode e)
|
||||||
@@ -499,6 +476,13 @@ buildErrorCode code = "PGRST" <> case code of
|
|||||||
ApiRequestErrorCode08 -> "108"
|
ApiRequestErrorCode08 -> "108"
|
||||||
ApiRequestErrorCode09 -> "109"
|
ApiRequestErrorCode09 -> "109"
|
||||||
ApiRequestErrorCode10 -> "110"
|
ApiRequestErrorCode10 -> "110"
|
||||||
|
ApiRequestErrorCode11 -> "111"
|
||||||
|
ApiRequestErrorCode12 -> "112"
|
||||||
|
ApiRequestErrorCode13 -> "113"
|
||||||
|
ApiRequestErrorCode14 -> "114"
|
||||||
|
ApiRequestErrorCode15 -> "115"
|
||||||
|
ApiRequestErrorCode16 -> "116"
|
||||||
|
ApiRequestErrorCode17 -> "117"
|
||||||
|
|
||||||
SchemaCacheErrorCode00 -> "200"
|
SchemaCacheErrorCode00 -> "200"
|
||||||
SchemaCacheErrorCode01 -> "201"
|
SchemaCacheErrorCode01 -> "201"
|
||||||
@@ -509,16 +493,4 @@ buildErrorCode code = "PGRST" <> case code of
|
|||||||
JWTErrorCode01 -> "301"
|
JWTErrorCode01 -> "301"
|
||||||
JWTErrorCode02 -> "302"
|
JWTErrorCode02 -> "302"
|
||||||
|
|
||||||
HasqlErrorCode00 -> "400"
|
InternalErrorCode00 -> "X00"
|
||||||
HasqlErrorCode01 -> "401"
|
|
||||||
HasqlErrorCode02 -> "402"
|
|
||||||
HasqlErrorCode03 -> "403"
|
|
||||||
HasqlErrorCode04 -> "404"
|
|
||||||
|
|
||||||
GeneralErrorCode00 -> "500"
|
|
||||||
GeneralErrorCode01 -> "501"
|
|
||||||
GeneralErrorCode02 -> "502"
|
|
||||||
GeneralErrorCode03 -> "503"
|
|
||||||
GeneralErrorCode04 -> "504"
|
|
||||||
GeneralErrorCode05 -> "505"
|
|
||||||
GeneralErrorCode06 -> "506"
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ spec = do
|
|||||||
[json|
|
[json|
|
||||||
{"hint": null,
|
{"hint": null,
|
||||||
"details": null,
|
"details": null,
|
||||||
"code": "PGRST506",
|
"code": "PGRST117",
|
||||||
"message":"Unsupported HTTP verb: CONNECT"}|]
|
"message":"Unsupported HTTP verb: CONNECT"}|]
|
||||||
{ matchStatus = 405 }
|
{ matchStatus = 405 }
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ spec = do
|
|||||||
[json|
|
[json|
|
||||||
{"hint": null,
|
{"hint": null,
|
||||||
"details": null,
|
"details": null,
|
||||||
"code": "PGRST506",
|
"code": "PGRST117",
|
||||||
"message":"Unsupported HTTP verb: TRACE"}|]
|
"message":"Unsupported HTTP verb: TRACE"}|]
|
||||||
{ matchStatus = 405 }
|
{ matchStatus = 405 }
|
||||||
|
|
||||||
@@ -51,6 +51,6 @@ spec = do
|
|||||||
[json|
|
[json|
|
||||||
{"hint": null,
|
{"hint": null,
|
||||||
"details": null,
|
"details": null,
|
||||||
"code": "PGRST506",
|
"code": "PGRST117",
|
||||||
"message":"Unsupported HTTP verb: OTHER"}|]
|
"message":"Unsupported HTTP verb: OTHER"}|]
|
||||||
{ matchStatus = 405 }
|
{ matchStatus = 405 }
|
||||||
|
|||||||
@@ -1013,21 +1013,21 @@ spec actualPgVersion = do
|
|||||||
it "fails if a single column is not selected" $ do
|
it "fails if a single column is not selected" $ do
|
||||||
request methodGet "/images?select=img,name&name=eq.A.png" (acceptHdrs "application/octet-stream") ""
|
request methodGet "/images?select=img,name&name=eq.A.png" (acceptHdrs "application/octet-stream") ""
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST502","details":null,"hint":null} |]
|
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST113","details":null,"hint":null} |]
|
||||||
{ matchStatus = 406 }
|
{ matchStatus = 406 }
|
||||||
|
|
||||||
request methodGet "/images?select=*&name=eq.A.png"
|
request methodGet "/images?select=*&name=eq.A.png"
|
||||||
(acceptHdrs "application/octet-stream")
|
(acceptHdrs "application/octet-stream")
|
||||||
""
|
""
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST502","details":null,"hint":null} |]
|
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST113","details":null,"hint":null} |]
|
||||||
{ matchStatus = 406 }
|
{ matchStatus = 406 }
|
||||||
|
|
||||||
request methodGet "/images?name=eq.A.png"
|
request methodGet "/images?name=eq.A.png"
|
||||||
(acceptHdrs "application/octet-stream")
|
(acceptHdrs "application/octet-stream")
|
||||||
""
|
""
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST502","details":null,"hint":null} |]
|
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST113","details":null,"hint":null} |]
|
||||||
{ matchStatus = 406 }
|
{ matchStatus = 406 }
|
||||||
|
|
||||||
it "concatenates results if more than one row is returned" $
|
it "concatenates results if more than one row is returned" $
|
||||||
|
|||||||
@@ -1024,7 +1024,7 @@ spec actualPgVersion =
|
|||||||
request methodPost "/rpc/ret_rows_with_base64_bin"
|
request methodPost "/rpc/ret_rows_with_base64_bin"
|
||||||
(acceptHdrs "application/octet-stream") ""
|
(acceptHdrs "application/octet-stream") ""
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST502","details":null,"hint":null} |]
|
[json| {"message":"application/octet-stream requested but more than one column was selected","code":"PGRST113","details":null,"hint":null} |]
|
||||||
{ matchStatus = 406 }
|
{ matchStatus = 406 }
|
||||||
|
|
||||||
context "only for GET rpc" $ do
|
context "only for GET rpc" $ do
|
||||||
@@ -1094,25 +1094,25 @@ spec actualPgVersion =
|
|||||||
it "fails when setting headers with wrong json structure" $ do
|
it "fails when setting headers with wrong json structure" $ do
|
||||||
get "/rpc/bad_guc_headers_1"
|
get "/rpc/bad_guc_headers_1"
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value","code":"PGRST500","details":null,"hint":null}|]
|
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value","code":"PGRST111","details":null,"hint":null}|]
|
||||||
{ matchStatus = 500
|
{ matchStatus = 500
|
||||||
, matchHeaders = [ matchContentTypeJson ]
|
, matchHeaders = [ matchContentTypeJson ]
|
||||||
}
|
}
|
||||||
get "/rpc/bad_guc_headers_2"
|
get "/rpc/bad_guc_headers_2"
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value","code":"PGRST500","details":null,"hint":null}|]
|
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value","code":"PGRST111","details":null,"hint":null}|]
|
||||||
{ matchStatus = 500
|
{ matchStatus = 500
|
||||||
, matchHeaders = [ matchContentTypeJson ]
|
, matchHeaders = [ matchContentTypeJson ]
|
||||||
}
|
}
|
||||||
get "/rpc/bad_guc_headers_3"
|
get "/rpc/bad_guc_headers_3"
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value","code":"PGRST500","details":null,"hint":null}|]
|
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value","code":"PGRST111","details":null,"hint":null}|]
|
||||||
{ matchStatus = 500
|
{ matchStatus = 500
|
||||||
, matchHeaders = [ matchContentTypeJson ]
|
, matchHeaders = [ matchContentTypeJson ]
|
||||||
}
|
}
|
||||||
post "/rpc/bad_guc_headers_1" [json|{}|]
|
post "/rpc/bad_guc_headers_1" [json|{}|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value","code":"PGRST500","details":null,"hint":null}|]
|
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value","code":"PGRST111","details":null,"hint":null}|]
|
||||||
{ matchStatus = 500
|
{ matchStatus = 500
|
||||||
, matchHeaders = [ matchContentTypeJson ]
|
, matchHeaders = [ matchContentTypeJson ]
|
||||||
}
|
}
|
||||||
@@ -1183,7 +1183,7 @@ spec actualPgVersion =
|
|||||||
it "fails when setting invalid status guc" $
|
it "fails when setting invalid status guc" $
|
||||||
get "/rpc/send_bad_status"
|
get "/rpc/send_bad_status"
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"response.status guc must be a valid status code","code":"PGRST501","details":null,"hint":null}|]
|
[json|{"message":"response.status guc must be a valid status code","code":"PGRST112","details":null,"hint":null}|]
|
||||||
{ matchStatus = 500
|
{ matchStatus = 500
|
||||||
, matchHeaders = [ matchContentTypeJson ]
|
, matchHeaders = [ matchContentTypeJson ]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ spec =
|
|||||||
[("Prefer", "tx=commit"), singular]
|
[("Prefer", "tx=commit"), singular]
|
||||||
[json| { address: "zzz" } |]
|
[json| { address: "zzz" } |]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 4 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 4 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [ matchContentTypeSingular
|
, matchHeaders = [ matchContentTypeSingular
|
||||||
, "Preference-Applied" <:> "tx=commit" ]
|
, "Preference-Applied" <:> "tx=commit" ]
|
||||||
@@ -85,7 +85,7 @@ spec =
|
|||||||
[("Prefer", "tx=commit"), ("Prefer", "return=representation"), singular]
|
[("Prefer", "tx=commit"), ("Prefer", "return=representation"), singular]
|
||||||
[json| { address: "zzz" } |]
|
[json| { address: "zzz" } |]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 4 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 4 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [ matchContentTypeSingular
|
, matchHeaders = [ matchContentTypeSingular
|
||||||
, "Preference-Applied" <:> "tx=commit" ]
|
, "Preference-Applied" <:> "tx=commit" ]
|
||||||
@@ -100,7 +100,7 @@ spec =
|
|||||||
request methodPatch "/items?id=gt.0&id=lt.0"
|
request methodPatch "/items?id=gt.0&id=lt.0"
|
||||||
[singular] [json|{"id":1}|]
|
[singular] [json|{"id":1}|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [matchContentTypeSingular]
|
, matchHeaders = [matchContentTypeSingular]
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ spec =
|
|||||||
request methodPatch "/items?id=gt.0&id=lt.0"
|
request methodPatch "/items?id=gt.0&id=lt.0"
|
||||||
[("Prefer", "return=representation"), singular] [json|{"id":1}|]
|
[("Prefer", "return=representation"), singular] [json|{"id":1}|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [matchContentTypeSingular]
|
, matchHeaders = [matchContentTypeSingular]
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ spec =
|
|||||||
[("Prefer", "tx=commit"), singular]
|
[("Prefer", "tx=commit"), singular]
|
||||||
[json| [ { id: 200, address: "xxx" }, { id: 201, address: "yyy" } ] |]
|
[json| [ { id: 200, address: "xxx" }, { id: 201, address: "yyy" } ] |]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [ matchContentTypeSingular
|
, matchHeaders = [ matchContentTypeSingular
|
||||||
, "Preference-Applied" <:> "tx=commit" ]
|
, "Preference-Applied" <:> "tx=commit" ]
|
||||||
@@ -157,7 +157,7 @@ spec =
|
|||||||
[("Prefer", "tx=commit"), ("Prefer", "return=representation"), singular]
|
[("Prefer", "tx=commit"), ("Prefer", "return=representation"), singular]
|
||||||
[json| [ { id: 202, address: "xxx" }, { id: 203, address: "yyy" } ] |]
|
[json| [ { id: 202, address: "xxx" }, { id: 203, address: "yyy" } ] |]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [ matchContentTypeSingular
|
, matchHeaders = [ matchContentTypeSingular
|
||||||
, "Preference-Applied" <:> "tx=commit" ]
|
, "Preference-Applied" <:> "tx=commit" ]
|
||||||
@@ -173,7 +173,7 @@ spec =
|
|||||||
[("Prefer", "tx=commit"), ("Prefer", "return=minimal"), singular]
|
[("Prefer", "tx=commit"), ("Prefer", "return=minimal"), singular]
|
||||||
[json| [ { id: 204, address: "xxx" }, { id: 205, address: "yyy" } ] |]
|
[json| [ { id: 204, address: "xxx" }, { id: 205, address: "yyy" } ] |]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [ matchContentTypeSingular
|
, matchHeaders = [ matchContentTypeSingular
|
||||||
, "Preference-Applied" <:> "tx=commit" ]
|
, "Preference-Applied" <:> "tx=commit" ]
|
||||||
@@ -189,7 +189,7 @@ spec =
|
|||||||
[singular]
|
[singular]
|
||||||
[json| [ ] |]
|
[json| [ ] |]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [matchContentTypeSingular]
|
, matchHeaders = [matchContentTypeSingular]
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,7 @@ spec =
|
|||||||
[("Prefer", "return=representation"), singular]
|
[("Prefer", "return=representation"), singular]
|
||||||
[json| [ ] |]
|
[json| [ ] |]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [matchContentTypeSingular]
|
, matchHeaders = [matchContentTypeSingular]
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ spec =
|
|||||||
[("Prefer", "tx=commit"), singular]
|
[("Prefer", "tx=commit"), singular]
|
||||||
""
|
""
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 5 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 5 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [ matchContentTypeSingular
|
, matchHeaders = [ matchContentTypeSingular
|
||||||
, "Preference-Applied" <:> "tx=commit" ]
|
, "Preference-Applied" <:> "tx=commit" ]
|
||||||
@@ -240,7 +240,7 @@ spec =
|
|||||||
request methodDelete "/items?id=gt.5&id=lt.11"
|
request methodDelete "/items?id=gt.5&id=lt.11"
|
||||||
[("Prefer", "tx=commit"), ("Prefer", "return=representation"), singular] ""
|
[("Prefer", "tx=commit"), ("Prefer", "return=representation"), singular] ""
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 5 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 5 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [ matchContentTypeSingular
|
, matchHeaders = [ matchContentTypeSingular
|
||||||
, "Preference-Applied" <:> "tx=commit" ]
|
, "Preference-Applied" <:> "tx=commit" ]
|
||||||
@@ -257,7 +257,7 @@ spec =
|
|||||||
request methodDelete "/items?id=lt.0"
|
request methodDelete "/items?id=lt.0"
|
||||||
[singular] ""
|
[singular] ""
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [matchContentTypeSingular]
|
, matchHeaders = [matchContentTypeSingular]
|
||||||
}
|
}
|
||||||
@@ -266,7 +266,7 @@ spec =
|
|||||||
request methodDelete "/items?id=lt.0"
|
request methodDelete "/items?id=lt.0"
|
||||||
[("Prefer", "return=representation"), singular] ""
|
[("Prefer", "return=representation"), singular] ""
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [matchContentTypeSingular]
|
, matchHeaders = [matchContentTypeSingular]
|
||||||
}
|
}
|
||||||
@@ -276,7 +276,7 @@ spec =
|
|||||||
request methodPost "/rpc/getproject"
|
request methodPost "/rpc/getproject"
|
||||||
[singular] [json|{ "id": 9999999}|]
|
[singular] [json|{ "id": 9999999}|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [matchContentTypeSingular]
|
, matchHeaders = [matchContentTypeSingular]
|
||||||
}
|
}
|
||||||
@@ -299,7 +299,7 @@ spec =
|
|||||||
request methodPost "/rpc/getallprojects"
|
request methodPost "/rpc/getallprojects"
|
||||||
[singular] "{}"
|
[singular] "{}"
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 5 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 5 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [matchContentTypeSingular]
|
, matchHeaders = [matchContentTypeSingular]
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ spec =
|
|||||||
[("Prefer", "tx=commit"), singular]
|
[("Prefer", "tx=commit"), singular]
|
||||||
[json| {"id_l": 1, "id_h": 2, "name": "changed"} |]
|
[json| {"id_l": 1, "id_h": 2, "name": "changed"} |]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"details":"Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST505","hint":null}|]
|
[json|{"details":"Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|]
|
||||||
{ matchStatus = 406
|
{ matchStatus = 406
|
||||||
, matchHeaders = [ matchContentTypeSingular
|
, matchHeaders = [ matchContentTypeSingular
|
||||||
, "Preference-Applied" <:> "tx=commit" ]
|
, "Preference-Applied" <:> "tx=commit" ]
|
||||||
|
|||||||
@@ -199,21 +199,21 @@ spec actualPgVersion =
|
|||||||
request methodPut "/tiobe_pls?name=eq.Javascript" [("Range", "0-5")]
|
request methodPut "/tiobe_pls?name=eq.Javascript" [("Range", "0-5")]
|
||||||
[json| [ { "name": "Javascript", "rank": 1 } ]|]
|
[json| [ { "name": "Javascript", "rank": 1 } ]|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"Range header and limit/offset querystring parameters are not allowed for PUT","code":"PGRST503","details":null,"hint":null}|]
|
[json|{"message":"Range header and limit/offset querystring parameters are not allowed for PUT","code":"PGRST114","details":null,"hint":null}|]
|
||||||
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
||||||
|
|
||||||
it "fails if limit is specified" $
|
it "fails if limit is specified" $
|
||||||
put "/tiobe_pls?name=eq.Javascript&limit=1"
|
put "/tiobe_pls?name=eq.Javascript&limit=1"
|
||||||
[json| [ { "name": "Javascript", "rank": 1 } ]|]
|
[json| [ { "name": "Javascript", "rank": 1 } ]|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"Range header and limit/offset querystring parameters are not allowed for PUT","code":"PGRST503","details":null,"hint":null}|]
|
[json|{"message":"Range header and limit/offset querystring parameters are not allowed for PUT","code":"PGRST114","details":null,"hint":null}|]
|
||||||
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
||||||
|
|
||||||
it "fails if offset is specified" $
|
it "fails if offset is specified" $
|
||||||
put "/tiobe_pls?name=eq.Javascript&offset=1"
|
put "/tiobe_pls?name=eq.Javascript&offset=1"
|
||||||
[json| [ { "name": "Javascript", "rank": 1 } ]|]
|
[json| [ { "name": "Javascript", "rank": 1 } ]|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"Range header and limit/offset querystring parameters are not allowed for PUT","code":"PGRST503","details":null,"hint":null}|]
|
[json|{"message":"Range header and limit/offset querystring parameters are not allowed for PUT","code":"PGRST114","details":null,"hint":null}|]
|
||||||
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
||||||
|
|
||||||
it "rejects every other filter than pk cols eq's" $ do
|
it "rejects every other filter than pk cols eq's" $ do
|
||||||
@@ -254,12 +254,12 @@ spec actualPgVersion =
|
|||||||
it "fails if the uri primary key doesn't match the payload primary key" $ do
|
it "fails if the uri primary key doesn't match the payload primary key" $ do
|
||||||
put "/tiobe_pls?name=eq.MATLAB" [json| [ { "name": "Perl", "rank": 17 } ]|]
|
put "/tiobe_pls?name=eq.MATLAB" [json| [ { "name": "Perl", "rank": 17 } ]|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"Payload values do not match URL in primary key column(s)","code":"PGRST504","details":null,"hint":null}|]
|
[json|{"message":"Payload values do not match URL in primary key column(s)","code":"PGRST115","details":null,"hint":null}|]
|
||||||
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
||||||
put "/employees?first_name=eq.Wendy&last_name=eq.Anderson"
|
put "/employees?first_name=eq.Wendy&last_name=eq.Anderson"
|
||||||
[json| [ { "first_name": "Susan", "last_name": "Heidt", "salary": "48000", "company": "GEX", "occupation": "Railroad engineer" } ]|]
|
[json| [ { "first_name": "Susan", "last_name": "Heidt", "salary": "48000", "company": "GEX", "occupation": "Railroad engineer" } ]|]
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|{"message":"Payload values do not match URL in primary key column(s)","code":"PGRST504","details":null,"hint":null}|]
|
[json|{"message":"Payload values do not match URL in primary key column(s)","code":"PGRST115","details":null,"hint":null}|]
|
||||||
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
{ matchStatus = 400 , matchHeaders = [matchContentTypeJson] }
|
||||||
|
|
||||||
it "fails if the table has no PK" $
|
it "fails if the table has no PK" $
|
||||||
|
|||||||
Reference in New Issue
Block a user