Also a lot of the proposals listed in the `Wrapping` section of https://seankhliao.com/blog/12020-11-23-go-error-handling-proposals/ On Wednesday, December 2, 2020 at 9:30:24 PM UTC+1 seank...@gmail.com wrote:
> see also > > https://github.com/golang/go/issues/41908 > https://github.com/golang/go/issues/37243 > https://github.com/gooid/gonotes/blob/master/inline_style_error_handle.md > > On Wednesday, December 2, 2020 at 8:57:13 PM UTC+1 Oliver Smith wrote: > >> Do I understand correctly that "last return value is error" is purely >> convention and there is no formal error handling in current go? >> >> My instinct is to leverage the 'else' keyword along with the notion of a >> "stock error whose return list's last element is type error with value != >> nil. >> >> func not_stock() (int, interface{}) >> func stock() error >> func stock() (int, error, string, float, error, error, error) >> func not_stock() (error, error, error, int) >> func stock() (error, error) >> >> Any other type of error handling can still be handled as the user wishes, >> stock errors simply provide syntax to lean into, and that syntax would be: >> >> [ <assignment> ] <call expr> ast.ELSE <block statement> >> >> e.g. >> >> file, err := io.Open(file) else { >> return nil, err >> } >> fh.Close() else { >> panic("close call failed") >> } >> >> Equivalent to: >> >> file, err := io.Open(file) >> if err != nil { >> return nil, err >> } >> if err := fh.Close(); err != nil { >> panic("close call failed") >> } >> >> One of the current nuisances of error handling is that it can break the >> clean flow of variable assignments, forcing you to add separate >> declarations or scopes. Given a function >> >> func NewStruct() (s *Struct, sz int, err error) >> >> you typically have two very different lifespans for the return values >> >> s, sz, err := NewStruct() >> if err != nil { // last reference to err in function >> >> vs >> >> if s, sz, err := NewStruct(); err != nil { >> panic(err) >> } else { >> // to access s and sz >> } >> >> or >> >> var ( >> s *Struct >> sz int >> err error // but literally only for one line >> ) >> if s, sz, err = NewStruct(); err != nil { >> panic(err) >> } >> >> Using the else construct always allows the shorter form, which is at >> least consistent: >> >> // not a sub-clause so s, sz and err introduced in current scope >> level. >> s, sz, err := NewStruct() else { >> panic(err) >> } >> >> The fly in the ointment here is ... where does the error go if you don't >> mention it? >> >> fh.Close() else { >> panic(?what?) >> } >> >> the lazy option would be `_` >> >> fh.Close() else { >> fmt.Errorf("unexpected close failure: %s", _) >> err := _ >> panic(err) >> } >> >> But I think we can avoid the path of perl, and simply require capture if >> you want the value surfaced. >> >> err := fh.Close() else { >> panic(err) >> } >> >> -- 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/8930f687-b52b-4013-852f-f40c36a6fc58n%40googlegroups.com.