ServerError represents an HTTP failure response in Servant. It carries the HTTP status code, reason phrase, response body, and headers, and can be thrown from a Handler with throwError. section 17.1.3 section 17.4
Use ServerError to choose between predefined responses and responses with application-specific details:
- Servant provides ready-made values such as err403, err404, err418, and err500, with status codes and reason phrases already set. section 17.1.3
- Record a database failure by replacing an error body's default empty ByteString with descriptive text from SQLError.sqlErrorDetails. section 17.1.3
- Customize a predefined error with record-update syntax, such as err422 {errBody}, to report an understood request that could not be processed. section 17.1.3
Returning database errors from a handler
addHandler addAct entry = do result <- liftIO $ addAct entry case result of Right idx -> pure idx Left exc -> let errBody = BSL.fromStrict (T.encodeUtf8 $ sqlErrorDetails exc) in throwError $ err422 {errBody} A missing todo entry can similarly use err404 with a body explaining the requested identifier. section 17.1.3
Listing 17.4 A Handler that adds a TodoEntry and returns descriptive errors
addHandler ::
(TodoEntry -> IO (Either SQLError Int)) ->
TodoEntry ->
Handler Int
addHandler addAct entry = do
mSqlError <- liftIO $ addAct entry #1
case mSqlError of
Right idx -> pure idx #2
Left exc ->
let errBody =
BSL.fromStrict #3
(T.encodeUtf8 $ sqlErrorDetails exc)
in throwError $ err422 {errBody} #4
Browse the complete addHandler implementation, including lifting the database action, pattern matching on Either, converting Text to lazy ByteString, and throwing err422. section 17.1.3
