Two things to note about this. First, if the "everything else" deferred to might include a return statement, then this could result in the same "silent failure" behavior.
Secondly - use this pattern with great caution. It is critical to confirm that a double close on ifDB is explicitly allowed. For example, if you have an io.Closer <https://golang.org/pkg/io/#Closer>, then, according to the documentation, the behavior of a double close is not specified. IMHO, if the package documentation does not explicitly allow double close, I would consider doing so to to be a bug. Only do this if you can confirm that a double close on ifDB On Thursday, March 21, 2019 at 6:11:04 AM UTC-4, rog wrote: > > This issue is why I like having idempotent close. Do: > > defer ifDB.Close() > > but also, after everything else is complete, do: > > if err := ifDB.Close(); err != nil { > handle error case > } > > That way if you return early on error your connection is still closed, but > you can still write the obvious code for checking the close error when > everything else has succeeded. > > > On Thu, 21 Mar 2019 at 09:41, Amnon Baron Cohen <amn...@gmail.com > <javascript:>> wrote: > >> The idiomatic Go way is to write >> >> defer ifDB.Close() >> >> Simple is better than clever. >> >> + Readability does matter. >> >> >> And in situations where you really need to check that the connection was >> successfully closed, and >> you have a workable scheme for recovering from this situation, then write >> a named helper function >> which encompasses this logic, rather than writing a convoluted anonymous >> function. >> >> And make sure that all the execution paths in this function have unit >> tests. >> >> >> >> On Tuesday, 19 March 2019 23:57:51 UTC, David Collier-Brown wrote: >>> >>> It's a known bad thing to defer a close for anything buffered, as >>> discussed at https://www.joeshaw.org/dont-defer-close-on-writable-files/ >>> but some constructs lack a Sync() call. >>> >>> For example, I have code like >>> ifDB, message, err := OpenInflux(server, debug) >>> if err != nil { >>> // If this fails, fail fast so we notice >>> panic(fmt.Errorf("failed to open and ping influxDB, %s >>> %v", >>> message, err)) >>> } >>> defer func() { >>> err = ifDB.Close() >>> if err != nil { >>> // This may be a harmless, very bad thing >>> panic(fmt.Errorf("failure closing connection to >>> influxDB, %v", err)) >>> } >>> }() >>> >>> >>> which closes an influxDB database, but will panic if the close fails. >>> >>> Separate logic makes sure I have passed the point at which the data is >>> committed before I commit my reading of input, so eventually the data will >>> be reread and rewritten. Nevertheless, this is exceedingly complex, and the >>> comment sums it up: "a harmless, very bad thing". >>> >>> Is there an idiomatic way to address this? I ended up reading influxDB >>> code and doing all sorts of deranged safety-critical-system DFAs to >>> reassure myself this will actually work, but every time I do that, my brain >>> hurts! >>> >>> --dave >>> >>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.