Home > database >  Haskell: How to report validation errors from command line arguments to user with proper exit codes
Haskell: How to report validation errors from command line arguments to user with proper exit codes

Time:06-28

I'm using getOpt to parse and validate the args provided by getArgs.

I chose to use the action based approach for getOpt, here are the types.

data Options = Options { afield :: foo, bfield :: bar}
type Action = Either String (Options -> Options)

Then I fold over the actions list on a default options record using,

evaluateActions :: Either [String] Options -> Action -> Either [String] Options
evaluateActions (Left errors) (Left err)      = Left $ err:errors
evaluateActions (Left errors) (Right _)       = Left errors
evaluateActions (Right _) (Left err)          = Left [err]
evaluateActions (Right option) (Right action) = Right $ action option

Afterwards I am left with the desired type Either [String] Options. Upon error(s), I want to print the strings out and exit with the error code InvalidArgument.

printErrorsThenExit :: [String] -> ExitCode -> IO ()
printErrorsThenExit errs code =
  hPutStr stderr (concat errs) >>
  exitWith code

I am struggling to glue this together in my main function without writing something like the following which doesn't work with the types:

opts <- case result of
          Left errors   -> printErrorsThenExit errors illegalArgument  
          Right options -> return options

I have seen the when function but I don't think it helps since I need to unwrap the Either.

Anyone know how I can express failure process in Haskell?

CodePudding user response:

Since we have

exitWith :: ExitCode -> IO a 

you can simply change your printErrorsThenExit type to

printErrorsThenExit :: [String] -> ExitCode -> IO a
                                               -- ^ --

The point is: if an IO action does not actually return (but exits the whole program) its type can be IO a for any a, claiming that it can fit any type.

Your main code should then just work as it is.

  • Related