diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs index 64e31b194..9f207de1f 100644 --- a/src/PostgREST/App.hs +++ b/src/PostgREST/App.hs @@ -168,7 +168,7 @@ postgrestResponse appState conf@AppConfig{..} maybeSchemaCache authResult@AuthRe timezones = dbTimezones sCache prefs = ApiRequest.userPreferences conf req timezones - (parseTime, apiReq@ApiRequest{..}) <- withTiming $ liftEither . mapLeft Error.ApiRequestError $ ApiRequest.userApiRequest conf prefs req body + (parseTime, apiReq@ApiRequest{..}) <- withTiming $ liftEither . mapLeft Error.ApiRequestErr $ ApiRequest.userApiRequest conf prefs req body (planTime, plan) <- withTiming $ liftEither $ Plan.actionPlan iAction conf apiReq sCache let mainQ = Query.mainQuery plan conf apiReq authResult configDbPreRequest diff --git a/src/PostgREST/Error.hs b/src/PostgREST/Error.hs index 5890e4889..c66fb63db 100644 --- a/src/PostgREST/Error.hs +++ b/src/PostgREST/Error.hs @@ -585,46 +585,46 @@ pgErrorStatus authed (SQL.SessionUsageError (SQL.QueryError _ _ (SQL.ResultError instance PgrstError Error where - status (ApiRequestError err) = status err - status (SchemaCacheErr err) = status err - status (JwtErr err) = status err - status NoSchemaCacheError = HTTP.status503 - status (PgErr err) = status err + status (ApiRequestErr err) = status err + status (SchemaCacheErr err) = status err + status (JwtErr err) = status err + status NoSchemaCacheError = HTTP.status503 + status (PgErr err) = status err - headers (ApiRequestError err) = headers err - headers (SchemaCacheErr err) = headers err - headers (JwtErr err) = headers err - headers (PgErr err) = headers err - headers NoSchemaCacheError = mempty + headers (ApiRequestErr err) = headers err + headers (SchemaCacheErr err) = headers err + headers (JwtErr err) = headers err + headers (PgErr err) = headers err + headers NoSchemaCacheError = mempty instance JSON.ToJSON Error where toJSON err = toJsonPgrstError (code err) (message err) (details err) (hint err) instance ErrorBody Error where - code (ApiRequestError err) = code err - code (SchemaCacheErr err) = code err - code (JwtErr err) = code err - code NoSchemaCacheError = "PGRST002" - code (PgErr err) = code err + code (ApiRequestErr err) = code err + code (SchemaCacheErr err) = code err + code (JwtErr err) = code err + code NoSchemaCacheError = "PGRST002" + code (PgErr err) = code err - message (ApiRequestError err) = message err + message (ApiRequestErr err) = message err message (SchemaCacheErr err) = message err message (JwtErr err) = message err message NoSchemaCacheError = "Could not query the database for the schema cache. Retrying." message (PgErr err) = message err - details (ApiRequestError err) = details err - details (SchemaCacheErr err) = details err - details (JwtErr err) = details err - details NoSchemaCacheError = Nothing - details (PgErr err) = details err + details (ApiRequestErr err) = details err + details (SchemaCacheErr err) = details err + details (JwtErr err) = details err + details NoSchemaCacheError = Nothing + details (PgErr err) = details err - hint (ApiRequestError err) = hint err - hint (SchemaCacheErr err) = hint err - hint (JwtErr err) = hint err - hint NoSchemaCacheError = Nothing - hint (PgErr err) = hint err + hint (ApiRequestErr err) = hint err + hint (SchemaCacheErr err) = hint err + hint (JwtErr err) = hint err + hint NoSchemaCacheError = Nothing + hint (PgErr err) = hint err instance PgrstError JwtError where status JwtDecodeErr{} = HTTP.unauthorized401 diff --git a/src/PostgREST/Error/Types.hs b/src/PostgREST/Error/Types.hs index ae4e2924f..778e558f2 100644 --- a/src/PostgREST/Error/Types.hs +++ b/src/PostgREST/Error/Types.hs @@ -29,7 +29,7 @@ import PostgREST.SchemaCache.Routine (Routine (..)) import Protolude data Error - = ApiRequestError ApiRequestError + = ApiRequestErr ApiRequestError | SchemaCacheErr SchemaCacheError | JwtErr JwtError | NoSchemaCacheError diff --git a/src/PostgREST/MainTx.hs b/src/PostgREST/MainTx.hs index 6a072e736..5d4e9818e 100644 --- a/src/PostgREST/MainTx.hs +++ b/src/PostgREST/MainTx.hs @@ -222,7 +222,7 @@ failPut :: ResultSet -> DbHandler () failPut RSStandard{rsQueryTotal=queryTotal} = when (queryTotal /= 1) $ do lift SQL.condemn - throwError $ Error.ApiRequestError Error.PutMatchingPkError + throwError $ Error.ApiRequestErr Error.PutMatchingPkError -- | -- Fail a response if a single JSON object was requested and not exactly one @@ -231,13 +231,13 @@ failNotSingular :: MediaType -> ResultSet -> DbHandler () failNotSingular mediaType RSStandard{rsQueryTotal=queryTotal} = when (elem mediaType [MTVndSingularJSON True, MTVndSingularJSON False] && queryTotal /= 1) $ do lift SQL.condemn - throwError $ Error.ApiRequestError . Error.SingularityError $ toInteger queryTotal + throwError $ Error.ApiRequestErr . Error.SingularityError $ toInteger queryTotal failExceedsMaxAffectedPref :: (Maybe PreferMaxAffected, Maybe PreferHandling) -> ResultSet -> DbHandler () failExceedsMaxAffectedPref (Nothing,_) _ = pure () failExceedsMaxAffectedPref (Just (PreferMaxAffected n), handling) RSStandard{rsQueryTotal=queryTotal} = when ((queryTotal > n) && (handling == Just Strict)) $ do lift SQL.condemn - throwError $ Error.ApiRequestError . Error.MaxAffectedViolationError $ toInteger queryTotal + throwError $ Error.ApiRequestErr . Error.MaxAffectedViolationError $ toInteger queryTotal -- | Set a transaction to roll back if requested optionalRollback :: AppConfig -> ApiRequest -> DbHandler () diff --git a/src/PostgREST/Plan.hs b/src/PostgREST/Plan.hs index e0d632ee4..5aca5698c 100644 --- a/src/PostgREST/Plan.hs +++ b/src/PostgREST/Plan.hs @@ -172,8 +172,8 @@ wrappedReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest wrappedReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} headersOnly = do qi <- findTable identifier sCache rPlan <- readPlan qi conf sCache apiRequest - (handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest qi iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan) - if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right () + (handler, mediaType) <- mapLeft ApiRequestErr $ negotiateContent conf apiRequest qi iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan) + if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestErr $ InvalidPreferences invalidPrefs else Right () return $ WrappedReadPlan rPlan SQL.Read handler mediaType headersOnly qi mutateReadPlan :: Mutation -> ApiRequest -> QualifiedIdentifier -> AppConfig -> SchemaCache -> Either Error CrudPlan @@ -181,8 +181,8 @@ mutateReadPlan mutation apiRequest@ApiRequest{iPreferences=Preferences{..},..} qi <- findTable identifier sCache rPlan <- readPlan qi conf sCache apiRequest mPlan <- mutatePlan mutation qi apiRequest sCache rPlan - if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right () - (handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest qi iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan) + if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestErr $ InvalidPreferences invalidPrefs else Right () + (handler, mediaType) <- mapLeft ApiRequestErr $ negotiateContent conf apiRequest qi iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan) return $ MutateReadPlan rPlan mPlan SQL.Write handler mediaType mutation qi callReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> InvokeMethod -> Either Error CrudPlan @@ -204,15 +204,15 @@ callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferenc (Inv, Routine.Immutable) -> SQL.Read (Inv, Routine.Volatile) -> SQL.Write cPlan = callPlan proc apiRequest paramKeys args rPlan - (handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest relIdentifier iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan) - if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right () + (handler, mediaType) <- mapLeft ApiRequestErr $ negotiateContent conf apiRequest relIdentifier iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan) + if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestErr $ InvalidPreferences invalidPrefs else Right () failMaxAffectedRpcReturnsSingle (preferMaxAffected, preferHandling) proc return $ CallReadPlan rPlan cPlan txMode proc handler mediaType invMethod identifier where qsParams' = QueryParams.qsParams iQueryParams failMaxAffectedRpcReturnsSingle :: (Maybe PreferMaxAffected, Maybe PreferHandling) -> Routine -> Either Error () - failMaxAffectedRpcReturnsSingle (Just (PreferMaxAffected _), Just Strict) rout = if funcReturnsSingle rout then Left $ ApiRequestError MaxAffectedRpcViolation else Right () + failMaxAffectedRpcReturnsSingle (Just (PreferMaxAffected _), Just Strict) rout = if funcReturnsSingle rout then Left $ ApiRequestErr MaxAffectedRpcViolation else Right () failMaxAffectedRpcReturnsSingle _ _ = Right () hasDefaultSelect :: ReadPlanTree -> Bool @@ -225,7 +225,7 @@ inspectPlan apiRequest headersOnly schema = do accepts = iAcceptMediaType apiRequest mediaType <- if not . null $ L.intersect accepts producedMTs then Right MTOpenAPI - else Left . ApiRequestError . MediaTypeError $ MediaType.toMime <$> accepts + else Left . ApiRequestErr . MediaTypeError $ MediaType.toMime <$> accepts return $ InspectPlan mediaType SQL.Read headersOnly schema {-| @@ -784,7 +784,7 @@ hoistIntoRelSelectFields _ r = r -- to order once it's aggregated if it's not selected in the inner query beforehand. addToManyOrderSelects :: ReadPlanTree -> Either Error ReadPlanTree addToManyOrderSelects (Node rp@ReadPlan{order, select, relAggAlias, relSelect, relSpread = Just ToManySpread {}} forest) - | anyAggSel || anyAggRelSel = Left $ ApiRequestError $ NotImplemented "Aggregates are not implemented for one-to-many or many-to-many spreads." + | anyAggSel || anyAggRelSel = Left $ ApiRequestErr $ NotImplemented "Aggregates are not implemented for one-to-many or many-to-many spreads." | otherwise = Node rp { order = [], relSpread = newRelSpread } <$> addToManyOrderSelects `traverse` forest where newRelSpread = Just ToManySpread { stExtraSelect = addSprExtraSelects, stOrder = addSprOrder} @@ -806,7 +806,7 @@ addToManyOrderSelects (Node rp forest) = Node rp <$> addToManyOrderSelects `trav validateAggFunctions :: Bool -> ReadPlanTree -> Either Error ReadPlanTree validateAggFunctions aggFunctionsAllowed (Node rp@ReadPlan {select} forest) - | not aggFunctionsAllowed && any (isJust . csAggFunction) select = Left $ ApiRequestError AggregatesNotAllowed + | not aggFunctionsAllowed && any (isJust . csAggFunction) select = Left $ ApiRequestErr AggregatesNotAllowed | otherwise = Node rp <$> traverse (validateAggFunctions aggFunctionsAllowed) forest -- | Lookup table in the schema cache before creating read plan @@ -860,9 +860,9 @@ addRelatedOrders (Node rp@ReadPlan{order,from} forest) = do name = fromMaybe relName relAlias in if isToOne == Just True then Right $ cot{coRelation=relAggAlias} - else Left $ ApiRequestError $ RelatedOrderNotToOne (qiName from) name + else Left $ ApiRequestErr $ RelatedOrderNotToOne (qiName from) name Nothing -> - Left $ ApiRequestError $ NotEmbedded coRelation + Left $ ApiRequestErr $ NotEmbedded coRelation -- | Searches for null filters on embeds, e.g. `projects=not.is.null` on `GET /clients?select=*,projects(*)&projects=not.is.null` -- @@ -956,7 +956,7 @@ addRanges ApiRequest{..} rReq = _ -> foldr addRangeToNode (Right rReq) =<< ranges where ranges :: Either Error [(EmbedPath, NonnegRange)] - ranges = first (ApiRequestError . QueryParamError) $ QueryParams.pRequestRange `traverse` HM.toList iRange + ranges = first (ApiRequestErr . QueryParamError) $ QueryParams.pRequestRange `traverse` HM.toList iRange addRangeToNode :: (EmbedPath, NonnegRange) -> Either Error ReadPlanTree -> Either Error ReadPlanTree addRangeToNode = updateNode (\r (Node q f) -> Node q{range_=r} f) @@ -990,7 +990,7 @@ updateNode f ([], a) rr = f a <$> rr updateNode _ _ (Left e) = Left e updateNode f (targetNodeName:remainingPath, a) (Right (Node rootNode forest)) = case findNode of - Nothing -> Left $ ApiRequestError $ NotEmbedded targetNodeName + Nothing -> Left $ ApiRequestErr $ NotEmbedded targetNodeName Just target -> (\node -> Node rootNode $ node : delete target forest) <$> updateNode f (remainingPath, a) (Right target) @@ -1014,7 +1014,7 @@ mutatePlan mutation qi ApiRequest{iPreferences=Preferences{..}, ..} SchemaCache{ _ -> False) qsFiltersRoot then mapRight (\typedColumns -> Insert qi typedColumns body (Just (MergeDuplicates, pkCols)) combinedLogic returnings mempty False) typedColumnsOrError else - Left $ ApiRequestError InvalidFilters + Left $ ApiRequestErr InvalidFilters MutationDelete -> Right $ Delete qi combinedLogic returnings where ctx = ResolverContext dbTables dbRepresentations qi "json" diff --git a/src/PostgREST/Response.hs b/src/PostgREST/Response.hs index 8498e7925..24ee29b4f 100644 --- a/src/PostgREST/Response.hs +++ b/src/PostgREST/Response.hs @@ -79,7 +79,7 @@ actionResponse (DbCrudResult plan@WrappedReadPlan{pMedia, wrHdrsOnly=headersOnly ++ cLHeader ++ contentTypeHeaders pMedia ctxApiRequest ++ prefHeader - bod | status == HTTP.status416 = Error.errorPayload $ Error.ApiRequestError $ Error.InvalidRange $ + bod | status == HTTP.status416 = Error.errorPayload $ Error.ApiRequestErr $ Error.InvalidRange $ Error.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show rsTableTotal) | headersOnly = mempty | otherwise = LBS.fromStrict rsBody @@ -183,7 +183,7 @@ actionResponse (DbCrudResult plan@CallReadPlan{pMedia, crInvMthd=invMethod, crPr (status, contentRange) = RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal rsTableTotal rsOrErrBody = if status == HTTP.status416 - then Error.errorPayload $ Error.ApiRequestError $ Error.InvalidRange + then Error.errorPayload $ Error.ApiRequestErr $ Error.InvalidRange $ Error.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show rsTableTotal) else LBS.fromStrict rsBody isHeadMethod = invMethod == InvRead True @@ -247,11 +247,11 @@ overrideStatusHeaders rsGucStatus rsGucHeaders pgrstStatus pgrstHeaders = do decodeGucHeaders :: Maybe BS.ByteString -> Either Error.Error [GucHeader] decodeGucHeaders = - maybe (Right []) $ first (const . Error.ApiRequestError $ Error.GucHeadersError) . JSON.eitherDecode . LBS.fromStrict + maybe (Right []) $ first (const . Error.ApiRequestErr $ Error.GucHeadersError) . JSON.eitherDecode . LBS.fromStrict decodeGucStatus :: Maybe Text -> Either Error.Error (Maybe HTTP.Status) decodeGucStatus = - maybe (Right Nothing) $ first (const . Error.ApiRequestError $ Error.GucStatusError) . fmap (Just . toEnum . fst) . decimal + maybe (Right Nothing) $ first (const . Error.ApiRequestErr $ Error.GucStatusError) . fmap (Just . toEnum . fst) . decimal contentLengthHeader :: LBS.ByteString -> HTTP.Header contentLengthHeader body = ("Content-Length", show (LBS.length body))