- http-media == 0.8.0.0
 - lucid == 2.9.12.1
 - mtl == 2.2.2
+- safe-exceptions == 0.1.7.1
 - servant == 0.18.2
 - servant-lucid == 0.9.0.2
 - servant-server == 0.18.2
 
 module Html where
 
 import ApiTypes
+import Control.Exception.Safe (SomeException)
 import Control.Monad (void)
 import Control.Monad.IO.Class (MonadIO(..), liftIO)
 import Data.List (sort)
 blogLink :: T.Text -> Maybe T.Text
 blogLink = T.stripSuffix markdownExtension
 
+blogNotFound :: (MonadIO m) => Maybe Theme -> BlogId -> SomeException -> m (Html ())
+blogNotFound theme blogId _ = htmlContainer theme $ do
+  div_ [class_ "not-found"] $ do
+    h1_ $ toHtml @T.Text "Blog not found"
+    p_ $ toHtml $ "Blog post " <> T.pack blogId <> " could not found."
+
 siteTitle :: T.Text
 siteTitle = "My Site"
 
 
 module Server where
 
 import ApiTypes
+import Control.Exception.Safe (handleAny)
 import Control.Monad ((<=<))
 import Control.Monad.IO.Class (liftIO)
 import Html
 mainPage = flip blogPost "index"
 
 blogPost :: Maybe Theme -> BlogId -> Handler (Html ())
-blogPost theme = htmlContainer theme . renderBlog <=< findBlogPost
+blogPost theme blogId = handleAny (blogNotFound theme blogId) $ findBlogPost blogId >>= htmlContainer theme . renderBlog
 
 findBlogPost :: BlogId -> Handler T.Text
 findBlogPost = liftIO . T.readFile . (<>) staticPath . flip (<>) (T.unpack markdownExtension)