Skip to content

Instantly share code, notes, and snippets.

@mastef
Created February 4, 2016 08:30
Show Gist options
  • Save mastef/05f46d3ab2f5ed6a6787 to your computer and use it in GitHub Desktop.
Save mastef/05f46d3ab2f5ed6a6787 to your computer and use it in GitHub Desktop.
os.IsExist(err) vs os.IsNotExist(err)
/*
Watch out, os.IsExist(err) != !os.IsNotExist(err)
They are error checkers, so use them only when err != nil, and you want to handle
specific errors in a different way!
Their main purpose is to wrap around OS error messages for you, so you don't have to test
for Windows/Unix/Mobile/other OS error messages for "file exists/directory exists" and
"file does not exist/directory does not exist"
This way you can handle such an error, while still failing on other unexpected errors like "permission denied",
"filesystem error", "wrong filename" error, etc.
*/
// We want to create a symlink, but the target path exists already :
if _, err := os.Symlink("/old/path", "/path/to/whatever"); os.IsExist(err) {
// error happened, can't Symlink
// can't create symlink because /path/to/whatever already exists
}
// We want to stat a file, but it doesn't exist :
if _, err := os.Stat("/path/to/whatever"); os.IsNotExist(err) {
// error happened, can't Stat!
// /path/to/whatever does not exist
}
// BUT :
// Anti-pattern : We want to stat a file, and continue if it exists :
if _, err := os.Stat("/file/that/exists"); os.IsExist(err) {
// will never trigger!
// why? because os.Stat runs normally if file exists.
// it's expected behaviour for os.Stat, so it doesn't throw an error
// os.IsExist() does not receive an error ( it's nil ), so it can't tell you
// if the error message was "file not found"
}
// Instead :
// We want to stat a file, and continue if it exists :
_, err := os.Stat("/file/that/exists");
if err != nil {
if os.IsNotExist(err) {
// file does not exist, do something
} else {
// more serious errors
}
}
// file exists.. continue with code here, or in else statement, or specify if err == nil { // do something }
/*
os.IsExist(err) is good for cases when you expect the file to not exist yet,
but the file actually exists :
*/
os.Symlink("/path/that/exists", "/path/to/symlink/target")
// os.IsExist(err) will trigger when target exists already
os.Mkdir(target)
// os.IsExist(err) will trigger because target path already exists
os.OpenFile(target, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
// os.IsExist(err) will trigger when target exists because O_EXCL means that file should not exist yet
/*
os.IsNotExist(err) is good for more common cases where you expect the file to exists,
but it actually doesn't exist :
*/
os.Chdir()
os.Stat()
os.Open()
os.OpenFile() // without os.O_EXCL
os.Chmod()
os.Chown()
os.Close()
os.Read()
os.ReadAt()
os.ReadDir()
os.Readdirnames()
os.Seek()
os.Truncate()
os.Write()
os.WriteAt()
os.WriteString()
// etc...
// More reading :
// http://stackoverflow.com/a/12518877
// http://stackoverflow.com/questions/25939584/file-both-exists-and-not-exists-in-go/25939743#25939743
//
// https://github.com/golang/go/search?utf8=%E2%9C%93&q=IsExist
// https://golang.org/pkg/os/#IsExist
//
// http://stackoverflow.com/search?q=os.IsExist
// http://stackoverflow.com/search?q=os.IsNotExist
@ggouzi
Copy link

ggouzi commented Apr 5, 2017

Thanks +1

@grewwc
Copy link

grewwc commented Aug 14, 2017

helpful!

@dastier
Copy link

dastier commented Feb 9, 2018

So the use of !os.IsNotExist is more convenient than os.IsExist

@wuxicn
Copy link

wuxicn commented Sep 19, 2018

Good! Thanks!

@tangx
Copy link

tangx commented Dec 19, 2018

helpful!!

@Smarticles101
Copy link

this helped me, i'm still starting with go

@Seekload
Copy link

Seekload commented Mar 9, 2021

Good! Thanks!

@tiagonevestia
Copy link

Good! Thanks!

@fanhang64
Copy link

Thanks

@ByZain
Copy link

ByZain commented Sep 23, 2022

helpful!! Thanks

@Zar-H
Copy link

Zar-H commented Jan 19, 2024

thanks a lot,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment