When I use ioutil
to read a file, it may return an error. But if I want to filter some error code, what should I do?
res, err := ioutil.ReadFile("xxx")
if err != nil {
fmt.Println(err.Error())
}
...
In the code snippet above, when a file has no permission, fmt.Println(err.Error())
will print "open xxxxx: permission denied
.
If I want to capture this kind error, how can I know that file read failed because permission was denied?
Should I search err.Error()
for the string permission denied
- this looks ungraceful. Is there any better way?
Thanks in advance.
Update
After trying @Intermernet solution, I found that it will not hit case os.ErrPermission
, it will hit default
and print "open xxx: Permission denied"
.
@Aedolon solution is ok, os.IsPermission(err)
can tell that a file has failed with permission deny.
According to the current API, ioutil.ReadFile
doesn't guarantee any specific behaviour except that it will return err == nil
when successful. Even the syscall package doesn't actually guarantee a specific error.
The current implementation of ioutil.ReadFile
uses os.Open
, which will return *os.PathError
when failing to open a file, not os.ErrPermission
or anything else. os.PathError
contains a field Err
which is also an error - in this case, a syscall.Errno
. The string "permission denied" is produced from a private table of error messages and it's both architecture and implementation-specific. In my Windows machine it says "Access is denied" instead.
AFAIK, the correct method is to use os.IsPermission(err)
, which will return true
in case of lacking permissions.
Per documentation, errors returned should be tested against these errors using errors.Is
var (
// ErrInvalid indicates an invalid argument.
// Methods on File will return this error when the receiver is nil.
ErrInvalid = errInvalid() // "invalid argument"
ErrPermission = errPermission() // "permission denied"
ErrExist = errExist() // "file already exists"
ErrNotExist = errNotExist() // "file does not exist"
ErrClosed = errClosed() // "file already closed"
ErrNoDeadline = errNoDeadline() // "file type does not support deadline"
)
As an example:
f, err := ioutil.ReadFile("your_file")
if err != nil {
if errors.Is(err, os.ErrNotExist) {
// your code
} else if errors.Is(err, os.ErrPermission) {
// your code
} else {
panic(err)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With