3

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?

Tomas Aschan
  • 58,548
  • 56
  • 243
  • 402
  • The full source is available here: https://github.com/tomasaschan/hello-servant – Tomas Aschan Apr 22 '20 at 20:44
  • Having glanced at your code, my strong suspicion - although not certainty - is that the error comes from your use of `printf` in the `ToJSON` instance of `CalendarDate Gregorian`. Unfortunately, I am not familiar with either of those libraries and the types seem "magical" enough that I cannot decode what your code is trying to do after merely briefly perusing the documentation. – Robin Zigmond Apr 22 '20 at 21:12
  • Although of course that wouldn't explain why you get the expected result when you specify an allowed sort order, so perhaps that's not it. – Robin Zigmond Apr 22 '20 at 21:24

1 Answers1

0

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?

ephrion
  • 2,687
  • 1
  • 14
  • 17
  • This is interesting. At least it confirms that my understanding of how things should work is bot too far off. I'm gonna delete my .stack-work folder and try again... – Tomas Aschan Apr 23 '20 at 05:43
  • OK, I found the error. It was completely unrelated to my Haskell code, but caused by how I looked at the response. To make it easier to read, I piped the output of `curl` to `jq`, which shows the error message I see. In other words, you'll be able to reproduce with `curl localhost:8081/users?sortby=foo | jq`. Thanks for trying it out and convincing me that the Haskell code was correct! – Tomas Aschan Apr 23 '20 at 06:08