proposal: Go 2: `onErr` simple macro for common case error handling. A #32437 counter-proposal.

This is a counter-proposal to the #32437. It uses the on err words proposed in #32611and #32848 but unlike #32611 it is specifically restricted to the ubiquitous and a defacto standard err identifier (variable) followed by a block, control-flow statement; or a call to the built-in panic() function.

Usage examples

c, err := fn()
onErr continue

c, err := fn()
onErr {

if r, err := fn(); onErr && triesleft > 0 {
  continue retry

if c, err := fn(); onErr {
    return 0, err

Go Specification amendments


log_op = "||" | "&&" .

Statements addition:

ctlflstmt       = ( ReturnStmt | BreakStmt | ContinueStmt | GotoStmt )
OnErrStmt       = "onErr" ctlflstmt
OnErrSimpleStmt = "onErr" ( block | log_op )

Blocks addition:

6.  ctlflstmt statement in the OnErrStmt is considered to be in its own implicit block.

onErr macro

to be added after Defer_statements.

The onErr macro simplifies repeatable error handling, checking whether err variable is not nil. Ie. the very onErr always is expanded to mean if err != nil. The err identifier must be in the scope.

After an onErr either a block, or five possible statements are allowed: continue, break, return, goto, and a call to panic(…) built-in. Then expansion occurs:

  1. The onErr always is expanded to the if err != nil statement.
  2. If there is a block or a logical or or and operator after the onErr, expansion ends.
  3. If there is an allowed statement, it acts as given in an implicit curly braces.


after recognizing an onErr token, hardcode the if err != nil template and subparse rest of the line. The core of the expansion likely will land somewhere within parser.go:2040 scope in the case _Onerr:

A macro?

@griesemer suggested that try is just a macro. So I dare to propose a macro too, based on an ‘invisible semicolons’ precedence and with a straightforward implementation.

thats all,




  • added explicit log_op to allow expansion in expression chains. Add usage example for it.

1 thought on “proposal: Go 2: `onErr` simple macro for common case error handling. A #32437 counter-proposal.

  1. As you’ve noted, this is short-hand for if err != nil in all cases. Personally I do not think this is a particularly useful construct nor does it add any more value beyond saving a handful of characters (as well as allowing syntax such as onErr continue, which is effectively a text substitution that also expands to include braces).

    I feel like this adds extra cognitive overload, without really delivering value to developers (my 2c!).

    Go need a hygienic macro feature where we can define macros ourselves

    I’m a big -1 on this idea – it will lead to everyones codebase being ‘specialised’, with custom macros and definitions all over the place. Switching between projects because a huge mental burden, and it starts to smell of similar features in other, older languages that quickly grow out of control.

Comments are closed.