if err != nil {
// handle error
}
Error handling seems to be a recurring theme in go, but most proposals get nowhere.
baseline code
x, err := foo()
if err != nil {
return nil, wrap(err)
}
note: almost all the ones that claim to use "plain functions" as error handlers have an implicit nonlocal return
handle err { return _, wrap(err) }
x := check foo()
: block scopedhandle err { return _, wrap(err) }
x, # := foo()
handle func(err error) (T, error) { return _, wrap(err) }
x, ? := foo()
watch err { if err != nil { return _, wrap(err) } }
x, err != foo()
expect err != nil { return _, wrap(err) }
x, err := foo()
with { return _, wrap(err) }
handle err { x, err := foo() }
x, #err := foo()
catch err { return _, wrap(err) }
: tagged error handlersx, @err := foo()
err: return _, wrap(err)
: goto labelgrab err() { if err != nil { return _, wrap(err) } }
x, err() := foo()
: assign to handlererr := inline(err error){ if err != nil { return _, wrap(err) } }
x, err := foo()
: assign to handlererr := func(err error) (T, error) { return _, wrap(err) }
x, #err := foo()
: block scoped_check = func(err error) (T, error) { return _, wrap(err)}
x, ?err := foo()
: not fully formed idea on returnhandler := func(err error) (T, error) { return^2 _, wrap(err) }
x, handler(err) := foo()
: note nonlocal returnsome rely on wrap
being smart and passing through nil
(so not fmt.Errorf
),
x, err := foo()
reflow _, wrap(err)
: implicit err != nil
and returnx, err := foo()
refuse _, wrap(err)
x, err := foo()
pass _, wrap(err)
x, err := foo()
ereturn _, wrap(err)
x, err := foo()
err ?: return _, wrap(err)
x, err := foo()
on err, return _, wrap(err)
x, err := foo()
err ? { return _, wrap(err) }
x, err := foo()
onErr { return _, wrap(err) }
x, err := foo()
if err != nil { return _, wrap(err) }
, also: if ... on 1 linex, err := foo()
if !err { return _, wrap(err) }
x, err := foo()
if err { return _, wrap(err) }
x, err := foo()
if err? { return _, wrap(err) }
x, err := foo(); if err != nil { return _, wrap(err) }
, also: everything on 1 linex, err := foo() /* err */ { return _, wrap(err) }
, alsox, err := foo() ?? { return _, wrap(err) }
x, err := foo(); err.return wrap(err)
x := foo() or err: return _, wrap(err)
x := foo() ?err return _, wrap(err)
x := check wrap() foo()
, alsox := foo() ? wrap()
x := foo() or wrap()
x := foo() || wrap(err)
x := foo() on_error err fail wrap(err)
x := foo() onerr return _, wrap(err)
x := try(foo(), wrap)
x := collect(&err, foo(), wrap)
try x, err := foo() { return _, wrap(err) }
can use defer
for wrapping
x := try(foo())
x := must(foo())
: panic instead of returnx := foo!()
x := foo()?
, alsox := #foo()
x := guard foo()
x := must foo()
x, # := foo()
: panic instead of returnx, ? := foo()
, alsox, ! := foo()
, also, panicx, !! := foo()
x, !err := foo()
x, ^err := foo()
x, err? := foo()
x, err := foo() throws err
tryfunc func(...){ x := foo() }
x, err := foo()
check(err)
: builtin if err != nil { return ..., err }
macrox, err := foo()
catch(err)
: builtin if err != nil { return ..., err }
macrotry { x := foo() } catch(e Exception) { ??? }
: literally try catchtry err != nil { x, err := foo() } except { return _, wrap(err) }
until err != nil { check x, err := foo() } else { return _, wrap(err) }
: insert after every check
break err != nil { step: x, err := foo() }
: insert after every repeatable labelbreak err != nil { try x, err := foo() }
: insert after every try
if x, err := foo(); err != nil { return _, wrap(err) } else { ... } undo { ??? } done { ??? } defer { ??? }
handler := func(err error) error { return wrap(err) }
check(handler){ x := foo() }
check { x := check foo() } handle err { return _, wrap(err) }
check { x, err1 := foo() } catch err { return _, wrap(err) }
check { x, err := foo()
catch: return _, wrap(err) }
x, err := foo() !!!
fail: return _, wrap(err)
: goto labelhandle err { x, err := foo()<br>case err != nil: return _, wrap(err) }
try { x := foo(); if err != nil { return _, wrap(err) } }
x, (err) := foo()
: only assign to LHS if ()
content is not currently nil
collect err { x, _! := foo() }
if err != nil { return _, wrap(err) }
: err is an value that accumulates errors? does it continue?errorhandling(err){ x, err := foo() }
: err is an accumulator? messes with typesx, err := foo()
handle err1 || err2 || err3 { return _, wrap(err) }
: shorter if chain?returnfrom label, err
: nonlocal returnvalue|err
allows passthrough