Re: [Haskell-cafe] error handling (esp. IO/exceptions)
Quoth br...@lorf.org, >> execute :: FilePath -> [String] -> IO (Either ExecuteError ExitCode) > > where 'ExecuteError' is a data type representing all the ways 'execute' > could fail and that 'execute p args' is supposed to > > * ensure p exists > * get p's permissions > * ensure p is readable > * ensure p is executable * read UNIX "magic number" from first 2 bytes of p case number of "#!" -> interpret rest of line, start validation process over on interpreter file valid executable type for OS -> OK _ -> not OK > * execute p and return its exit code Donn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] error handling (esp. IO/exceptions)
Quoth br...@lorf.org, > On Tuesday, 14.04.09 at 22:13, Lennart Augustsson wrote: >> So the right way to do this (like opening a file), is to try executing >> it and let the OS tell you if it failed. > > I know, but the various functions that create processes don't help me > know whether the program actually ran or not. For example, > >> createProcess (proc "nosuch" []) >>= \(_,_,_,ph) -> waitForProcess ph > > returns ExitCode 127. If I use the same code to run 'test', a C program > that returns 127, I get the same thing. Right, awkward problem. Don't know if it can be solved in a portable way, but you (as author of a createProcess-like function) can use a pipe from the forked process. The code demo I append works, given FFI support for the POSIX functions it uses, but may not be appropriate for use with GHC (I'm using nhc98.) Donn spawn file cmd env = do (e0, e1) <- pipe -- F_CLOEXEC: close fd on (sucessful) exec. fcntlSetFlag e1 F_CLOEXEC t <- fork (fex e0 e1) close e1 rx <- readFd e0 256 if null rx then return t else ioError (userError rx) where fex e0 e1 = do close e0 catch (execve file cmd env) (\ e -> writeFd e1 (ioeGetErrorString e)) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] error handling (esp. IO/exceptions)
On Tuesday, 14.04.09 at 22:13, Lennart Augustsson wrote: > So the right way to do this (like opening a file), is to try executing > it and let the OS tell you if it failed. I know, but the various functions that create processes don't help me know whether the program actually ran or not. For example, > createProcess (proc "nosuch" []) >>= \(_,_,_,ph) -> waitForProcess ph returns ExitCode 127. If I use the same code to run 'test', a C program that returns 127, I get the same thing. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] error handling (esp. IO/exceptions)
On Tue, 14 Apr 2009, br...@lorf.org wrote: On Tuesday, 14.04.09 at 23:36, Miguel Mitrofanov wrote: What about ErrorT monad transformer? I don't see how it helps in my situation. ErrorT doesn't catch exceptions, for example. Suppose I did make something like ErrorT that catches exceptions and turn them into Lefts. Where would (>>=) get my specific error constructor? With explicit-exception you would call Exc.fromEitherT $ try $ execute path options The package has some hidden modules, where I experiment with a special IO type that cannot throw exceptions. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] error handling (esp. IO/exceptions)
On Tue, 14 Apr 2009, Miguel Mitrofanov wrote: What about ErrorT monad transformer? Well, if it's not what you really want, you can define your own one without ugly "Error" class, so it'd be something like execute :: FilePath -> [String] -> MyCoolErrorT ExecuteError IO ExitCode My MyCoolErrorT is named Control.Monad.Exception.Synchronous.ExceptionalT and can be found in the explicit-exception package. In contrast to ErrorT it puts no restrictions on the exception type. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] error handling (esp. IO/exceptions)
There's no way to make all your tests atomically, e.g, between the test that p exists and executing p, some other process could removce p. So the right way to do this (like opening a file), is to try executing it and let the OS tell you if it failed. On Tue, Apr 14, 2009 at 9:29 PM, wrote: > I'm finding it hard to write robust code that isn't really ugly. Suppose > I want to write > >> execute :: FilePath -> [String] -> IO (Either ExecuteError ExitCode) > > where 'ExecuteError' is a data type representing all the ways 'execute' > could fail and that 'execute p args' is supposed to > > * ensure p exists > * get p's permissions > * ensure p is readable > * ensure p is executable > * execute p and return its exit code > > So 'ExecuteError' would have constructors corresponding to these ways to > fail: > * could not determine whether p exists > * p does not exist > * could not get p's permissions > * p is not readable > * p is not executable > * could not execute p for some other reason > > So if I start to code it, I 'tryJust' 'doesFileExist'. If an exception > is thrown, I convert it to Left $AppropriateExecuteError. If not, we > know whether p exists. If it doesn't, convert it to Left. Otherwise, > 'tryJust' 'getPermissions', etc. It's starting to staircase. > > I'm needing it to be easier to stop my computation and return specific > things when exceptions are thrown or when certain requirements aren't > met. Thanks for any help. > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] error handling (esp. IO/exceptions)
On Tuesday, 14.04.09 at 23:36, Miguel Mitrofanov wrote: > What about ErrorT monad transformer? I don't see how it helps in my situation. ErrorT doesn't catch exceptions, for example. Suppose I did make something like ErrorT that catches exceptions and turn them into Lefts. Where would (>>=) get my specific error constructor? Maybe I need to make helper functions to use in runErrorT blocks that turn exceptions, Bools, Maybes, etc., into Eithers? Confused. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] error handling (esp. IO/exceptions)
What about ErrorT monad transformer? Well, if it's not what you really want, you can define your own one without ugly "Error" class, so it'd be something like execute :: FilePath -> [String] -> MyCoolErrorT ExecuteError IO ExitCode On 14 Apr 2009, at 23:29, br...@lorf.org wrote: I'm finding it hard to write robust code that isn't really ugly. Suppose I want to write execute :: FilePath -> [String] -> IO (Either ExecuteError ExitCode) where 'ExecuteError' is a data type representing all the ways 'execute' could fail and that 'execute p args' is supposed to * ensure p exists * get p's permissions * ensure p is readable * ensure p is executable * execute p and return its exit code So 'ExecuteError' would have constructors corresponding to these ways to fail: * could not determine whether p exists * p does not exist * could not get p's permissions * p is not readable * p is not executable * could not execute p for some other reason So if I start to code it, I 'tryJust' 'doesFileExist'. If an exception is thrown, I convert it to Left $AppropriateExecuteError. If not, we know whether p exists. If it doesn't, convert it to Left. Otherwise, 'tryJust' 'getPermissions', etc. It's starting to staircase. I'm needing it to be easier to stop my computation and return specific things when exceptions are thrown or when certain requirements aren't met. Thanks for any help. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe