[Haskell-cafe] unexpected behavior / bug in try . System.FilePath.Find.findWithHandler

Thomas Hartman tphyahoo at gmail.com
Tue Jan 5 15:40:29 EST 2010


say you want to execute a find function, but abort the computation if
it hits any snags, such as an unreadable directory (eg chmod -R a-r
dir).

Currently try . System.FilePath.Find.findWithHandler

will return an exception wrapped in Right, which seems Wrong. For sure
it will just get ignored if wrapped in an ErrorT computation and I
suspect this could lead to other glitchy/unexpected behavior when used
in sysadmin scripts.

You do get the expected exception wrapped in Left for certain errors
(such as a missing directory), which adds to the confusion.

Probable fix: you get the expected behavior if you remove
unsafeInterleaveIO from findWithHandler. Does this seem like a
reasonable thing to suggest to libraries at haskell?

Hacky fix: I haven't actually done this, but I suppose you could trap
stdout or stderr, since the exception does get printed although it's
not reflected in the result type of the computation.

demo of problem:

import qualified System.FilePath.Find as F
import System.FilePath.Find
import System.IO.Error

abort path err = fail $ path ++ " , " ++ (show err)

prot = "/home/thartman/protected" -- a protected (unreadable) dir

{-
want result =>
  Left user error (/home/thartman/protected , user error
(/home/thartman/protected , /home/thartman/protected:
getDirectoryContents: permission denied (Permission denied)))
but get result
  Right *** Exception: user error (/home/thartman/protected ,
/home/thartman/protected: getDirectoryContents: permission denied
(Permission denied))
which means, for example, you would miss the error if you wrapped this
in an ErrorT
there is probably a workaround from reading stderr, since it does get
printed out, but this is awkward compared to just catching the error
the right way
  and certainly feels like unexpected behavior
Possible fix: you get the expected behavior if you remove
unsafeInterleaveIO from System.FilePath.Find.findWithHandlers
  don't know why this fixes the problem, I was just messing around
  I don't know if this breaks anything else, but I was unable to find
any breakage when I did a simple test on an unprotected directory
  What is the gain from unsafeInterleaveIO, and can it be nixed?
-}
tprot = try . findWithHandler abort (return True) (return True) $ prot

tunprot = return . either (error . show) (length) =<<  ( try $
findWithHandler abort (return True) (return True) unprot )

unprot = "/home/thartman/unprot"



-- 
Need somewhere to put your code? http://patch-tag.com
Want to build a webapp? http://happstack.com


More information about the Haskell-Cafe mailing list