cover

Go and Error Handling: A Final (Almost) Word

The Go team recently what feels like a final update on a long-debated topic: error handling.

After years of proposals, experiments, and community discussions, the conclusion is simple and clear:

The current approach is considered good enough, and there’s no plan to change it.

The post explains that many alternative designs were explored, some even prototyped, but none of them made a compelling enough case to justify a language change — though the team remains open to community input.

The most promising proposal (IMO)

Out of all the options discussed over the years, the one I find most aligned with Go’s philosophy is a compact ? syntax for handling errors.

Example:

res, err := doSomething() ?

Here’s the idea:

You could even manipulate the error inline before returning:

res, err := doSomething() ? fmt.Errorf("problem with %q", param)

This avoids repetitive if blocks while still keeping the error flow explicit and customizable.

Compared to the classic approach

The current Go idiom:

val, err := strconv.Atoi(input)
if err != nil {
    return err
}

With ?, that becomes:

val, err := strconv.Atoi(input) ?

Behavior stays the same.

But it’s cleaner, less noisy, and easier to follow, especially when the same pattern repeats across multiple lines.

More complex example:

func printSum(a, b string) error {
    x, err := strconv.Atoi(a)
    if err != nil {
        return fmt.Errorf("invalid a: %w", err)
    }

    y, err := strconv.Atoi(b)
    if err != nil {
        return fmt.Errorf("invalid b: %w", err)
    }

    fmt.Println("result:", x + y)
}

Could become:

x, err := strconv.Atoi(a) ? return fmt.Errorf("invalid a: %w", err)
y, err := strconv.Atoi(b) ? return fmt.Errorf("invalid b: %w", err)
fmt.Println("result:", x + y)

An alternative — not a replacement

Let’s be clear:

This kind of syntax isn’t meant to replace the existing error handling in Go. It’s meant to complement it.

The familiar if err != nil remains 100% valid and is still necessary when you need custom error logic.

The ? operator would be just an alternative for the most common patterns — a shorthand, not a shift in philosophy.

And since Go’s compiler already understands function signatures, propagating errors where appropriate would be safe and predictable.

Default return values (nil, 0, "", etc.) would be inferred, just as they are today.

Why I (partially) disagree with the Go team

Go values explicitness, simplicity, and predictability. The verbosity of its error handling reflects those values. That’s totally fair.

But still — in the vast majority of cases, error handling in Go is formulaic: check error, return or panic.

Recognizing that, and providing a built-in syntax for it, wouldn’t hurt Go’s clarity. In fact, Go already supports concise syntax when it improves readability, like the := short declaration.

The ? operator would just follow that same principle:

optional, minimal, idiomatic.

Other languages (Rust, PHP, Kotlin, etc.) use ? to represent a similar idea: short-circuiting on failure. For many developers, that syntax already feels familiar.

The “just let the IDE handle it” argument

The blog post also brings up the idea that IDEs and AI tools could abstract away error boilerplate.

That’s fine in theory — but in practice, you don’t want language clarity to depend on external tools.

Relying too much on auto-generation or snippets risks hiding the actual behavior, especially in shared or open source codebases.

Clean syntax should be a language-level feature, not an IDE convenience.

Final thoughts

Providing a more ergonomic syntax for error propagation wouldn’t dilute Go’s identity. It would just make the most common code patterns cleaner and easier to write.

A proposal like ?, with clearly defined semantics and full backward compatibility, would:

What’s your take on this?

Reach me out on my socials .