diff --git a/Spock.cabal b/Spock.cabal
--- a/Spock.cabal
+++ b/Spock.cabal
@@ -1,5 +1,5 @@
 name:                Spock
-version:             0.6.4.0
+version:             0.6.5.0
 synopsis:            Another Haskell web framework for rapid development
 description:         This toolbox provides everything you need to get a quick start into web hacking with haskell: routing, middleware, json, blaze, sessions, cookies, database helper, csrf-protection, global state
 Homepage:            https://github.com/agrafix/Spock
diff --git a/src/Web/Spock.hs b/src/Web/Spock.hs
--- a/src/Web/Spock.hs
+++ b/src/Web/Spock.hs
@@ -13,7 +13,7 @@
     , combineRoute
      -- * Handeling requests
     , request, header, cookie, body, jsonBody, jsonBody', files, UploadedFile (..)
-    , params, param
+    , params, param, param'
      -- * Sending responses
     , setStatus, setHeader, redirect, jumpNext, setCookie, setCookie', bytes, lazyBytes
     , text, html, file, json, blaze
diff --git a/src/Web/Spock/Core.hs b/src/Web/Spock/Core.hs
--- a/src/Web/Spock/Core.hs
+++ b/src/Web/Spock/Core.hs
@@ -6,7 +6,7 @@
     , middleware, UploadedFile (..)
     , defRoute, get, post, head, put, delete, patch
     , request, header, cookie, body, jsonBody, jsonBody'
-    , files, params, param, setStatus, setHeader, redirect
+    , files, params, param, param', setStatus, setHeader, redirect
     , jumpNext
     , setCookie, setCookie'
     , bytes, lazyBytes, text, html, file, json, blaze
@@ -121,7 +121,6 @@
          Left err ->
              do setStatus status500
                 text (T.pack $ "Failed to parse json: " ++ err)
-                throwError ActionDone
          Right val ->
              return val
 
@@ -153,6 +152,17 @@
          Nothing ->
              return $ join $ fmap fromPathPiece (lookup k qp)
 
+-- | Like 'param', but outputs an error when a param is missing
+param' :: (PathPiece p, MonadIO m) => T.Text -> ActionT m p
+param' k =
+    do mParam <- param k
+       case mParam of
+         Nothing ->
+             do setStatus status500
+                text (T.concat [ "Missing parameter ", k ])
+         Just val ->
+             return val
+
 -- | Set a response status
 setStatus :: MonadIO m => Status -> ActionT m ()
 setStatus s =
@@ -168,7 +178,7 @@
 jumpNext = throwError ActionTryNext
 
 -- | Redirect to a given url
-redirect :: MonadIO m => T.Text -> ActionT m ()
+redirect :: MonadIO m => T.Text -> ActionT m a
 redirect = throwError . ActionRedirect
 
 -- | Set a cookie living for a given number of seconds
@@ -194,41 +204,43 @@
                       ]
 
 -- | Send a 'ByteString' as response body. Provide your own "Content-Type"
-bytes :: MonadIO m => BS.ByteString -> ActionT m ()
+bytes :: MonadIO m => BS.ByteString -> ActionT m a
 bytes val =
     lazyBytes $ BSL.fromStrict val
 
 -- | Send a lazy 'ByteString' as response body. Provide your own "Content-Type"
-lazyBytes :: MonadIO m => BSL.ByteString -> ActionT m ()
+lazyBytes :: MonadIO m => BSL.ByteString -> ActionT m a
 lazyBytes val =
-    modify $ \rs -> rs { rs_responseBody = ResponseLBS val }
+    do modify $ \rs -> rs { rs_responseBody = ResponseLBS val }
+       throwError ActionDone
 
 -- | Send text as a response body. Content-Type will be "text/plain"
-text :: MonadIO m => T.Text -> ActionT m ()
+text :: MonadIO m => T.Text -> ActionT m a
 text val =
     do setHeader "Content-Type" "text/plain"
        bytes $ T.encodeUtf8 val
 
 -- | Send a text as response body. Content-Type will be "text/plain"
-html :: MonadIO m => T.Text -> ActionT m ()
+html :: MonadIO m => T.Text -> ActionT m a
 html val =
     do setHeader "Content-Type" "text/html"
        bytes $ T.encodeUtf8 val
 
 -- | Send a file as response
-file :: MonadIO m => T.Text -> FilePath -> ActionT m ()
+file :: MonadIO m => T.Text -> FilePath -> ActionT m a
 file contentType filePath =
      do setHeader "Content-Type" contentType
         modify $ \rs -> rs { rs_responseBody = ResponseFile filePath }
+        throwError ActionDone
 
 -- | Send json as response. Content-Type will be "application/json"
-json :: (A.ToJSON a, MonadIO m) => a -> ActionT m ()
+json :: (A.ToJSON a, MonadIO m) => a -> ActionT m b
 json val =
     do setHeader "Content-Type" "application/json"
        lazyBytes $ A.encode val
 
 -- | Send blaze html as response. Content-Type will be "text/html"
-blaze :: MonadIO m => Html -> ActionT m ()
+blaze :: MonadIO m => Html -> ActionT m a
 blaze val =
     do setHeader "Content-Type" "text/html"
        lazyBytes $ renderHtml val
