Search code examples
haskellservant

Correctly handle invalid query parameter in Servant


I'm following along with the Servant tutorial, and I've defined the following API type:

type UsersAPI = "users" :> QueryParam "sortby" SortBy :> Get '[JSON] [UserData]

data SortBy = Id | Name | Age

instance FromHttpApiData SortBy where
  parseQueryParam input =
    case toLower input of
      "name" -> Right Name
      "age"  -> Right Age
      _      -> Left $ append "Invalid sort order: " input

listUsers :: Maybe SortBy -> Handler [UserData]
listUsers = return . Db.getUsers . fromMaybe Id -- Db.getUsers just returns a a sorted in-memory list...

-- rest of implementation ommitted for brevity

Something is obviously correct, because if I curl localhost:8081/users?sortby=name or curl localhost:8081/users?sortby=age I get a correctly sorted list back. However, something is also broken, because curl localhost:8081/users?sortby=foo doesn't give me the expected Invalid sort order: foo. Instead, I get

parse error: Invalid numeric literal at line 1, column 6

What am I doing wrong?


Solution

  • I am unable to replicate the issue after cloning your repository. On inspection, the code all looks fine, aside from the dodgy fromJust calls.

    Your repository also doesn't even build, by default - the stack.yaml file must be modified to include the allow-newer: true field. If you're using cabal, then it's impossible to know what versions of dependencies you're using, which will make troubleshooting this quite difficult.

    Once this has been done, I get exactly the message you'd expect:

    the expected error output

    and all the sorting works just fine.

    Can you post more details on your system? How are you building the project? What dependencies are in use?