Frage

In the System.Directory library, getPermissions function could return IO errors. The documentation says it could fail with isPermissionError or isDoesNotExistError. How do I handle IO errors during calling getPermissions?

Attempt:

input <- try (do 
        permissions <- getPermissions filepath 
        print permissions)
case input of
        Left e  -> print "a"
        Right e -> print "b"

Error:

No instance for (Exception e0) arising from a use of ‘try’
The type variable ‘e0’ is ambiguous
Note: there are several potential instances:
  instance Exception NestedAtomically
    -- Defined in ‘Control.Exception.Base’
  instance Exception NoMethodError
    -- Defined in ‘Control.Exception.Base’
  instance Exception NonTermination
    -- Defined in ‘Control.Exception.Base’
  ...plus 7 others
In a stmt of a 'do' block:
  input <- try
             (do { permissions <- getPermissions filepath;
                   print permissions })
In the expression:
  do { input <- try
                  (do { permissions <- getPermissions filepath;
                        print permissions });
       case input of {
         Left e -> print "a"
         Right e -> print "b" } }
In an equation for ‘checkwritefilepermissions’:
    checkwritefilepermissions filepath
      = do { input <- try
                        (do { permissions <- getPermissions filepath;
                              print permissions });
             case input of {
               Left e -> print "a"
               Right e -> print "b" } }
War es hilfreich?

Lösung

The error message says it was impossible to figure out the type of exception (that is, the instance of Exception) you want to catch. One possible solution is providing a type annotation which specifies it, as in:

case (input :: Either IOError String) of
    Left e -> print "a"
    Right r -> print "b"

Alternatively, if you use isDoesNotExistError and friends in System.IO.Error to distinguish the error cases the exception type will be inferred as IOError without requiring extra annotations.

A relevant discussion of basic exception catching practices can be found in the Control.Exception documentation.

Andere Tipps

There is an easy fix (not a best fix) to this problem, replace

Left e

by

Left (e :: SomeException)

By the way, your code could be simplified like this

input <- try $ getPermissions filepath
case input of
    Left (e :: SomeException) -> print "a"
    Right e -> print "b"

And you really should improve those names in your code.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top