Interesting, the chaining is a nice idea. However, wouldn't that mean that I would still have to errors.Is a specific error. So I would have to handle both. Which is fine ofc. Just saying. :)
On Thursday, 27 October 2022 at 19:51:14 UTC+2 Konstantin Khomoutov wrote: > On Thu, Oct 27, 2022 at 06:23:31AM -0700, Gergely Brautigam wrote: > > > I was wondering what's the consensus these days on handling defer > errors? > > > > Is it something like, overwriting the returned value, or using a list of > > errors? > > > > Either: > > > > func test() (err error) { > > defer func() { > > if tmpErr := doSomething(); tmpErr != nil { > > err = tmpErr > > } > > }() > > > > err = doSomethingElse() > > return err > > } > > > > Or: > > func test() (errList []error) { > > defer func() { > > if tmpErr := doSomething(); tmpErr != nil { > > errList = append(errList, tmpErr) > > } > > }() > > > > if err := doSomethingElse(); err != nil { > > errList = append(errList, err) > > } > > return errList > > } > > > > Or even something else entirely? > > I think you're falling into a common trap: there's no need to have any > sort of > consensus here because what you have demonstrated are two approaches to > tackle > a problem, and they depend on what you're after. > Sure, I was merely trying to ascertain what other people are doing in this area. :) > > One could easily add other variations. > For sure, just simply logging the error is also an option. > > For instance, often you want to Close() a resource on an error path out; > calling Close might itself return an error, and sometimes this error is > less > severe than the "original" one. As an example, consider opening a network > socket and then doing some setup on it: say, socket creation went OK but > the > setup failed, so you'd want to return the error about the failed setup > operation, and if closing the socket on the way out fails for some reason, > you could possibly ignore this error. Of may be you can log it. > > On the other hand, if, say, you had a file opened for writing, wrote some > data > to it, then some error has happened, and you're aborting the operation > returning that error, and closing of the file on the way out fails, this > might > be a severe enough error because it might indicate some data which was > written > got lost. What to do about it? There's no ready answer. You could > construct a > custom error with a compound error message, like "error X has happened > while > Y, and also closing of F has failed during cleanup". > Right, you could indeed return a compound error that contains the "ClosingError" or something like that. That's also a nice idea. :) > > You can also return a list of errors. > Or create a custom type implenting the error interface which holds a list > of > errors. > > Since Go 1.13 you can also make chains of errors; say, in your second > example > you could do > > err = fmt.Errorf("doSomething failed with %s while handling %w", > tmpErr, err) > > and then have callers use errors.Is / errors.As or whatever other approach > to > learn whether the error of their interest is in the error chain. > > Note that in ether approach with returning multiple errors, the callers > are to > be prepared to handle multiple errors; otherwise it's engineering for the > sake > of engineering which leads to nothing more than code which is convoluted > for > nothing. > > So I'd recommend to start small, use the simplest approach possible until > you > see clear need to use a more complex one, and then decide what looks/works > best in a particular case. I know, this is a glib piece of advice, but > it's > really how the things are ;-) > Sure, that's fine. :) I was just trying to gauge what people use. -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/1c365b80-4986-4f9c-9f77-7adf5ced894bn%40googlegroups.com.