Skip to content

proposal: spec: goto error handler with @err #72153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
3 of 4 tasks
daku opened this issue Mar 7, 2025 · 3 comments
Open
3 of 4 tasks

proposal: spec: goto error handler with @err #72153

daku opened this issue Mar 7, 2025 · 3 comments
Labels
error-handling Language & library change proposals that are about error handling. LanguageChange Suggested changes to the Go language LanguageChangeReview Discussed by language change review committee Proposal
Milestone

Comments

@daku
Copy link

daku commented Mar 7, 2025

Go Programming Experience

Intermediate

Other Languages Experience

Swift, C, C++, JS, Kotlin, Python, Java

Related Idea

  • Has this idea, or one like it, been proposed before?
  • Does this affect error handling?
  • Is this about generics?
  • Is this change backward compatible? Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit

Has this idea, or one like it, been proposed before?

Yes. Similar issues are:

How this issue is different:

This proposal is backwards compatible, allows handling errors before returning, reduces boilerplate, is clear where each error is handled and the scope of variables available during error handling, provides an explicit declaration that execution continue after error handling if needed, and is easy to read and understand.

Does this affect error handling?

Yes

Related proposals and how this differs:
#43777 - similar to try/catch so unclear if a function returns an error while reading the code. Specific error types has to be known for proper handling from multiple functions. The scope of which handler "catches" what error is not clear.
#56126 - forces return from function without actually handling error. No custom error handling allowed. The magic handleErr function is unclear in what it does. Syntax looks very incompatible with current go syntax.
#62378 - forces return without handling error. Syntax is unclear (hard to read) as well.
#70151 - proposes executing any function returning an error within an error context. Thus, all functions returning errors must be wrapped in 'ctx.Do(...)' call making syntax hard to accept. Also, does not allow continuing after an error occurs and only first error in a series of steps (function calls) can be handled and maybe function must return after that.

Is this about generics?

No

Proposal

Goals of this error handling proposal in order of importance:

  • Backwards compatibility with previous golang versions
  • Be able to do all the things we are able to do today, for example
    • do something before returning the error
    • choose to continue execution or return after handling error
    • have access to all variables in callee's scope while handling error
  • Avoid boiler plate error checking/handling code that exists today
  • No steep learning curve, should be easy-to-read and understand

Synopsis:

I am proposing a new statment block called eswitch that handles errors that are returned in the same scope. Errors indicate that they want to be handled by an eswitch block by preceding the error variable name by an @ sign. If an error occurs, control jumps to the respective case statement in the eswitch block. From there, function can return or control can continue after the line where the error occurred. See the eswitch example below.

Code example (contains several scenarios):

func main() {
	// TRADITIONAL WAY
	// usual way to handle errors today
	// this continues to work
	m, err1 := someFunc()
	if err1 != nil {
		// handle err1
		log.Println("error on call to someFunc", err1)
		return
	}

	// NEW PROPOSAL
	// using @<error variable name> implies error will 
	// be handled in the eswitch block closest in scope. 
	// Compiler error occurs if no eswitch block is found.
        // if error occurs, control jumps to the case statement 
        // where this error is being handled in the eswitch block.
        // see `eswitch` block at the end of this function.
	i, @eFunc1 := func1()
	if i < 3 {
		var lvar = 3
		j, @eFunc2 := func2()
		log.Println("result of func2", j)
	}

	// disambiguation with different error name for
	// second call to func1 
	k, @eFunc1CallTwo := func1()

	// block-scoped so can be written in any block. Will handle
	// errors that are returned in the same block-scope.
	eswitch {
	case eFunc1:
                 log.Println("error on 1st call to func1", eFunc1)
		continue  // implies flow continues after first call to func1
	case eFunc2:
		// all variables in scope of where func2 was called should
		// be available here. In this case we should be able to
		// access 'lvar'
		log.Println("locally scoped variable", lvar)
		return // this means return from the function
	case eFunc1CallTwo:
		log.Println("error on 2nd call to func1", eFunc1CallTwo)
		return
	// should we have a default case for
	// all unhandled errors? Is that even
	// benefecial?
	}
}

func func1() (int, error) {
	return 1, errors.New("func1 error")
}

func func2() (int, error) {
	return 2, errors.New("func2 error")
}

func someFunc() (int, error) {
	return 3, errors.New("someFunc error")
}

Is this change backward compatible?

Yes. See above example.

@daku daku added LanguageChange Suggested changes to the Go language LanguageChangeReview Discussed by language change review committee Proposal labels Mar 7, 2025
@gopherbot gopherbot added this to the Proposal milestone Mar 7, 2025
@seankhliao seankhliao added the error-handling Language & library change proposals that are about error handling. label Mar 7, 2025
@daku
Copy link
Author

daku commented Mar 7, 2025

Sorry, its probably because I am not as proficient with compilers. Would anyone downvoting be willing to share what are the main issues with the proposal?

@BieHDC
Copy link

BieHDC commented Mar 7, 2025

Would anyone downvoting be willing to share what are the main issues with the proposal?

The TL;DR would be: its goto with extra steps and noise.

I dont see how this would make anything anyhow better. New Keywords, new magic decorators, more indirection and less linear functions, changes meaning of existing keywords depending on context, nothing that makes it more clear what is going on, no compiler level optimisations this would enable. It looks like its wants to be magic, but all it does is smell.
It does the opposite of what i love about Go.

I am a forever if err != niler, because it is always clear whats going on whenever you see this, even for someone who has just started learning. You can collapse the scope block in any basic IDE making it very easy to follow along even longer and more complex functions because it provides an easy way to hide "error handling noise".

No one has managed to propose a type of error handling that would be so significantly better that it would be worth throwing this beautiful and predictable pattern away.
Please stop trying to make everything magic. Just write the basic for loop, just use a map and just if err != nil it.

@daku
Copy link
Author

daku commented Mar 7, 2025 via email

@seankhliao seankhliao changed the title proposal: spec: backwards compatible error handling without boilerplate or try/catch proposal: spec: go-to error handler with @err Mar 7, 2025
@seankhliao seankhliao changed the title proposal: spec: go-to error handler with @err proposal: spec: goto error handler with @err Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error-handling Language & library change proposals that are about error handling. LanguageChange Suggested changes to the Go language LanguageChangeReview Discussed by language change review committee Proposal
Projects
None yet
Development

No branches or pull requests

4 participants