Skip to content
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

proposal: spec: check / handle with extra arguments #68720

Closed
2 of 4 tasks
maxnorth opened this issue Aug 2, 2024 · 5 comments
Closed
2 of 4 tasks

proposal: spec: check / handle with extra arguments #68720

maxnorth opened this issue Aug 2, 2024 · 5 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 Proposal-FinalCommentPeriod
Milestone

Comments

@maxnorth
Copy link

maxnorth commented Aug 2, 2024

Go Programming Experience

Intermediate

Other Languages Experience

C#, JS/TS, Python, Ruby

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?

I don't believe so, I'm pretty familiar with the history of error handling proposals and this is not quite like any that I've seen. It's inspired by this former proposal, with some intentional adjustments.

Does this affect error handling?

Yeah, sorry. But I think I've found a good approach that addresses the main concerns I've seen come out of error handling discussions:

  • The syntax is pretty clear and not excessively magical
  • It doesn't significantly change the style of error handling in Go
  • It does not introduce horizontal complexity
  • It allows customizing the handling of every error, such as wrapping it

Is this about generics?

No

Proposal

Here's an example:

func example() (string, error) {
  handle (err error, msg string) {
    if err != nil {
      // a `return` here returns the example() function. if no return, continue executing after `check`
      return "", errors.Wrap(err, msg)
    }
  }

  user, err := createUser()
  check err, "error creating user"
 
  account, err := createAccount(user)
  check err, "error creating account"

  return account.ID, nil
}

As mentioned above, this is a minor redesign of this former proposal. Notable similarities and differences highlighted below.

Similarities

  • Introduces keywords handle and check.
    • handle allows defining a custom handler for determining if the function should or should not return and how to modify the returned error.
    • check is used to invoke the handle code and pass the error, and each check is a potential termination point for the function.

Differences

  • handle
    • Can receive more than one argument, the user defines them like a function.
      • This allows for defining per-scenario patterns about which additional context should be included when evaluating the errors.
  • check
    • Not intended to be used inline, and it does not provide unwrapping of return values from functions. It does not bake in the assumption of a single error object as the last return value from a function.
    • check statements are still used underneath each function call.
      • This feels familiar of Go's style of emphasizing these flow control points in a left-most location on a line for clear vertical readability.
      • I also like how you can read an error's custom message clearly in the above example, and without the clutter of errors.Wrap(...) on every line.

Language Spec Changes

  • handle and check keywords
  • handle resembles a function but has slightly unique syntax and behaviors
    • the handle keyword replaces the func keyword, it does not have a name, and it does not specify return values
    • return applies to the outer function and uses its return value signature
    • allows for code paths without a return statement, which will allow execution to resume at the check point
  • check is syntactically the same as a return statement

Informal Change

This approach allows you to define a reusable error handler at the top of your function, and then you can easily invoke it at each point that you check an error, which keeps the main function code clear and simple.

Is this change backward compatible?

I believe this would be backward compatible, I don't see any reason it shouldn't be.

Orthogonality: How does this change interact or overlap with existing features?

No response

Would this change make Go easier or harder to learn, and why?

No response

Cost Description

No response

Changes to Go ToolChain

No response

Performance Costs

No response

Prototype

No response

@maxnorth maxnorth added LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change labels Aug 2, 2024
@gopherbot gopherbot added this to the Proposal milestone Aug 2, 2024
@seankhliao seankhliao added the error-handling Language & library change proposals that are about error handling. label Aug 2, 2024
@ianlancetaylor
Copy link
Contributor

Thanks. As mentioned in #40432, one of the major reasons that the original check/handle proposal was rejected was that the distinction between handle and defer was unclear. Is handle dynamic? What happens if you use handle in a block? Any new proposal along these lines has to address those kinds of questions.

@seankhliao seankhliao changed the title proposal: Go 2: Yet Another Error Handling Proposal proposal: Go 2: check / handle with extra arguments Aug 2, 2024
@donuts-are-good

This comment was marked as abuse.

@ianlancetaylor ianlancetaylor changed the title proposal: Go 2: check / handle with extra arguments proposal: spec: check / handle with extra arguments Aug 6, 2024
@ianlancetaylor ianlancetaylor added LanguageChangeReview Discussed by language change review committee and removed v2 An incompatible library change labels Aug 6, 2024
@ianlancetaylor
Copy link
Contributor

This is fairly similar to the original check/handle proposal. It doesn't resolve the main issues with that proposal. Emoji voting is not in favor. Therefore, this is a likely decline. Leaving open for four weeks for final comments.

@ianlancetaylor
Copy link
Contributor

No further comments.

@ianlancetaylor ianlancetaylor closed this as not planned Won't fix, can't repro, duplicate, stale Sep 4, 2024
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 Proposal-FinalCommentPeriod
Projects
None yet
Development

No branches or pull requests

6 participants