jaspervdj / digestive-functors

A general way to consume input using applicative functors
149 stars 71 forks source link

choice breaks with an empty array #40

Open ocharles opened 12 years ago

ocharles commented 12 years ago

Consider the following:

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Control.Monad.IO.Class (liftIO)
import Snap.Blaze
import Snap.Core
import Snap.Http.Server
import Text.Digestive
import Text.Blaze.Html
import Text.Digestive.Blaze.Html5
import Text.Digestive.Snap

testForm :: (MonadSnap m) => Form Html m Int
testForm = "choice" .: choice [] Nothing

main :: IO ()
main = quickHttpServe handler
  where handler = do (v, i) <- runForm "f" testForm
                     case i of
                       Just r -> liftIO $ print "I'm about to crash!" >> print r
                       Nothing -> blaze (view v)
        view v = form v "foo" $ do inputSelect "choice" v
                                   inputSubmit "Explode!"

Expected output: the form does not validate Actual output:

A web handler threw an exception. Details:
Prelude.(!!): index too large
jaspervdj commented 12 years ago

Crashing is indeed not the way to go. It'll be a bit annoying that you can't specify a custom error here, but something like: "choice: Internal error: empty list given" should be alright, I guess?

In most cases, you'll want to prevent the end user from ever seeing this error :-)

ocharles commented 12 years ago

It's a tricky one! On the one hand, I don't like having an error at all because it feels like it should be valid to construct that form (in fact, the types say so). Of course there's no way to submit the form, so it should just constantly fail validation. However, baking in validation messages to the form system itself is a bit iffy, because that could make it difficult to translate error messages (when we get to translation, years down the line :)).

An error message as you gave is still going to be very annoying, because errors in Haskell just plain suck. It'd be nicer if there was more context (digestive-functors: choice requires a non empty list. Choice field 'format' is an empty list! for example), but I'm not sure this is possible due to where names are specified.