Home > database >  go - Cleanup resources only when the function is about to return an error
go - Cleanup resources only when the function is about to return an error

Time:02-06

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?

  • Related