2 ms·
What about the situation where you need to clean up a little but you can't "handle" the error yourself? A simple example being 1. Open a file for reading
by RHSeeger 7y ago
What about the situation where you need to clean up a little but you can't "handle" the error yourself? A simple example being
1. Open a file for reading
2. Try to open a file for writing, but error
3. Close the file that was opened for reading
4. Propagate the error upwards (because the reason this function was called failed)
- klodolph 7y agoThis is just returning the error upwards, as far as I can tell. This is the pattern I usually see in actual Go codebases: infp, err := os.Open(infile) if err != nil { return err } defer infp.Close() outfp, err := os.Create(outfile) if err != nil { return err } defer outfp.Close() // ... do some stuff ... return outfp.Close() Note that double-close is explicitly OK, this pattern just avoids losing the error.
- wst_ 7y agoCould you, please, expand on double closing? I can't find any good reason to do it.
- klodolph 7y agoOn a file open for writing, close(2) may return EIO. If you ignore the error, you have silent data loss. So you must propagate the error. The double-close pattern is just the easy way to accomplish this in go. You defer fp.Close(), and then return fp.Close(). The return fp.Close() closes the file and propagates the error. Afterwards, the deferred fp.Close() executes, but this simply returns an error (which is ignored) because the file is already closed. The behavior of fp.Close(), the fact that it is safe to call multiple times, is documented in the Go documentation. There are alternative ways to achieve the same effect but they require more code. So I use the double-close pattern everywhere, and then put a comment in every time I use it.