MyNixOS website logo
Description

Extensible exceptions for servant APIs.

`servant-exceptions` provides a Throw combinator to declare what types of errors an API might throw. The server implementation catches them and allows for a canonical encoding using servant content-type machinery.

servant-exceptions Build Status

Servant servers typically run their handlers in some form of IO. Either directly in the builtin Handler monad or a custom monad transformer on top it. When APIs fail, one would typically use the MonadError ServantError instance via throwError to create an error response of type ServantErr.

This approach has two problems:

  • Handler (basically being ExceptT ServantErr IO) is considered an anti-pattern by some, as it suggests to novice users that only ServantErr would occur, but in IO any exception can be raised to abort execution
  • ServantErr values need to be created at the call site of throwError, where the requested content type and/or headers are not available

servant-exceptions tries to help with both by making it easy to catch specific error types with an instance of Exception and provide automatic encoding into the requested content-type.

The API combinator Throws e can be used to annotate what error types e might be thrown by a server, for example:

type API = "api" :> Throws UsersError :> "users" :> Get '[JSON, PlainText] [User]

The type UsersError can then be used to describe expected errors and their conversion via type class instances:

data UsersError = UserNotFound
                | UserAlreadyExists
                | InternalError
                deriving (Show)

instance Exception UsersError

instance ToServantErr UsersError where
  status UserNotFound = status404
  status UserAlreadyExists = status409
  status InternalError = status500

instance ToJSON UsersError where
  toJSON e = object [ "type" .= show (typeOf e)
                    , "message" .= message e
                    ]

instance MimeRender PlainText UsersError where
  mimeRender ct = mimeRender ct . show

See example for a full, commented example.

Packages

Features

  • Declarative conversion of errors into error responses using ToServantErr
  • Respects Accept headers and constructs responses accordingly using MimeRender
  • Add headers to error responses, also via ToServantErr
  • Type-driven exception handling in ServerT stacks
  • Convert "backend" errors into "api" errors using mapException

Planned things

This package lacks at least

  • servant-client to rethrow exceptions (using MonadThrow and/or MonadError?)
  • servant-docs support for automatic error documentation
  • Documentation, more examples (explain included ServantException helper type)

Credit

This package is inspired by servant-checked-exceptions (Throws combinator) and the generalized error handling in cardano-sl.

Metadata

Version

0.2.1

Platforms (77)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-windows
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows