In the last (and not only the last) time, many copies are broken about the inconvenience of error handling in Go.
The essence of the claims is that direct use:
')
customVar, err := call() if err != nil { doSomething(err) return err }
on large numbers of repetitions is much less convenient than the classic:
try { String customVar = call(); } catch (BadException e) { doSomething(e); sendException(); }
One can argue for a long time both on the subject of the claims and on the
workarounds , however, there is indeed logic in the “package” approach.
In this connection, I had an idea about the handling of exceptions without much deviation from the “Go-way”. The option is
not working - just my imagination.
It would look like this:
try err { customVar1, err := call1() customVar2, err := call2() customVar3, err := call3() } catch { doSomething(err) return err }
The general idea is this: right after try, a variable (in our case, err) of type error is declared, the scope of which is the entire try ... catch block. Further, each time a new value is assigned to a variable inside a try block, the compiler checks it for nil, and if an error is returned, the transition to the catch block follows. Theoretically, this is not a very expensive operation, performance should not suffer.
It is also possible to assign several variables, such as:
try errIo, errNet { customVarIo1, errIo := callIo1() customVarIo2, errIo := callIo2() customVarNet1, errNet := callNet1() customVarNet2, errNet := callNet2() } catch { if errIo != nil { doSomething(errIo) return errIo } else { doSomething(errNet) return errNet } }
In this case, the example is not very visual, but with a large amount of code inside the try, it can be useful to group the errors so that the catch does not reduce their processing to:
switch err { case net.Error1: doSomethingWithNetError() case net.Error2: doSomethingWithNetError() case io.Error1: doSomethingWithIoError() case io.Error2: doSomethingWithIoError() }
In general, I have everything. Scold.