module IHP.Controller.NotFound ( notFoundWhen , notFoundUnless , handleNotFound , buildNotFoundResponse , renderNotFound ) where import IHP.Prelude hiding (displayException) import IHP.Controller.RequestContext import Network.HTTP.Types (status404) import Network.Wai import Network.HTTP.Types.Header import qualified Text.Blaze.Html.Renderer.Utf8 as Blaze import qualified Data.ByteString.Lazy as LBS import IHP.HSX.QQ (hsx) import qualified System.Directory as Directory import IHP.Controller.Context import IHP.Controller.Response (respondAndExit) -- | Stops the action execution with a not found message (404) when the access condition is True. -- -- __Example:__ Checking a user is the author of a blog post. -- -- > action EditPostAction { postId } = do -- > post <- fetch postId -- > notFoundWhen (post.authorId /= currentUserId) -- > -- > renderHtml EditView { .. } -- -- This will throw an error and prevent the view from being rendered when the current user is not the author of the post. notFoundWhen :: (?context :: ControllerContext) => Bool -> IO () notFoundWhen condition = when condition renderNotFound -- | Stops the action execution with a not found message (404) when the access condition is False. -- -- __Example:__ Checking a user is the author of a blog post. -- -- > action EditPostAction { postId } = do -- > post <- fetch postId -- > notFoundUnless (post.authorId == currentUserId) -- > -- > renderHtml EditView { .. } -- -- This will throw an error and prevent the view from being rendered when the current user is not the author of the post. notFoundUnless :: (?context :: ControllerContext) => Bool -> IO () notFoundUnless condition = unless condition renderNotFound -- | Renders a 404 not found response. If a static/404.html exists, that is rendered instead of the IHP not found page handleNotFound :: Request -> Respond -> IO ResponseReceived handleNotFound request respond = do response <- buildNotFoundResponse respond response buildNotFoundResponse :: IO Response buildNotFoundResponse = do hasCustomNotFound <- Directory.doesFileExist "static/404.html" if hasCustomNotFound then customNotFoundResponse else pure defaultNotFoundResponse -- | The default IHP 404 not found page defaultNotFoundResponse :: Response defaultNotFoundResponse = responseBuilder status404 [(hContentType, "text/html")] $ Blaze.renderHtmlBuilder [hsx|
Action not found