Suppose I have a function that starts by creating a directory, and then doing some more stuff, like this:
{
err := os.Mkdir(path, os.ModePerm)
...
err = doSomething()
if err != nil {
return nil, err
}
err = doSomethingElse()
if err != nil {
return nil, err
}
return path, nil
}
Now, I want the function to delete the directory it created in all of those cases where an error occured. What is the cleanest way to do this?
One way would be to call os.RemoveAll
in every if
branch, but that's not a very nice solution. Another way would be to use a defer
statement, but that would also get executed in the case where there was no error.
CodePudding user response:
Yes, a deferred function will always be executed, but whether it deletes the directory depends entirely on you.
Use a deferred function, and check the error. If there was no error, do not delete the directory. For this to work, use named result parameters, e.g.:
func foo() (result resultType, err error) {
path := "some folder"
defer func() {
if err != nil { // This is the result err
if err2 := os.RemoveAll(path); err2 != nil {
// handle err2
}
}
}()
err := os.Mkdir(path, os.ModePerm)
...
}
Note that if there is an explicit return
stament like:
return path, errors.New("bar")
The above return
statement first assigns the values to result
and err
, so in deferred functions you can get / see those values.
See related: How to return a value in a Go function that panics?