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: catch error model, a rethink of check/handle #67859

Closed
1 of 4 tasks
xiaokentrl opened this issue Jun 6, 2024 · 18 comments
Closed
1 of 4 tasks

proposal: spec: catch error model, a rethink of check/handle #67859

xiaokentrl opened this issue Jun 6, 2024 · 18 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

@xiaokentrl
Copy link

xiaokentrl commented Jun 6, 2024

Go Programming Experience

Intermediate

Other Languages Experience

JavaScript、PHP、C#、Delphi、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?

I don't think so, but considering how many error handling proposals there have been over the years it is possible.

Does this affect error handling?

Yes. It differs in that it doesn't attempt to handle errors in a magical way, but instead introduces a new syntax that can be used for several different types of common data handling.

Is this about generics?

No.

Proposal

Set ENV

ERROR_SINGLE = TRUE   //error_single = true

Demo1:

//Single-line error handling
file, err := os.Create("abc.txt") @ return nil , err
defer file.Close()

Demo2:

func main() {

    //Multiline error handling
    :@

    file, err:= os.Open("abc.txt")
    defer file.Close()

    buf := make([]byte, 1024)
    _, err2 := file.Read(buf)

    @ err | err2  return ... 
}

Language Spec Changes

Two main changes: Add a block and add the operator and associated rules.with

Informal Change

No response

Is this change backward compatible?

I think so, but it should be possible to create an alternative that is if it is not. The parts that are potentially no backwards compatible are basically just implementation details.

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

It enables separation of repeated error handling from the happy path of the code.

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

Slightly harder, but I don't think that it's overly complicated. It adds a new type of control flow, but I think that the main complication would probably come from the rules surrounding how the pattern matching works.

Cost Description

Some extra complexity. Possible runtime cost, but very minimal if it exists at all. It's mostly just syntax sugar. Most possible cost could come from some potentially unnecessary type switches, but it might be possible to optimize those away at compile-time in most cases.

Changes to Go ToolChain

Have no effect

Performance Costs

Likely minimal in both cases.

Prototype

No response

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

In the multiline form, does a non-nil error value effectively become a goto to the @ line? There have been several proposals with similar features. It's hard to handle declarations. Note that you can't use goto to a label that has additional variables in scope, but that is exactly what is happening in your example.

@gabyhelp
Copy link

gabyhelp commented Jun 8, 2024

Similar Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

@susugagalala
Copy link

Why not have Ian Lance Taylor and/or some other people from the core Go team come up with the initial prototype of the improved error handling framework, and then have the Go community participate, contributing towards its final form? This was exactly how generics in Go evolved to what it is now. If instead we wait for the Go community to come up with the initial prototype, I don't think we will ever have an improved Go error handling framework, at least not in the next few years.

@gophun
Copy link

gophun commented Jun 8, 2024

@susugagalala The Go team already did (twice), the last one being #32437. This was the most downvoted proposal on the Go issue tracker of all time. This was countered by the community proposal #32825 to leave error handling as it is. This is the most upvoted Go proposal of all time.

@atdiar
Copy link

atdiar commented Jun 8, 2024

@susugagalala that has been done a couple times. For instance #32437

Eventually, that might depend on the evolution of the language.
For example, if we were to have variadic generics at some point, I can imagine that a function returning a pair composed of a try function and an error handling object could be defined, in user-code even.

try, erro := exec.New()
v:= try(SomeFallibleFunc(a, b))
w:= try(io.Read(v))

if erro.Check(){
    return erro.Value()
} 

There would be other things necessary to make variable shadowing a non-problem. (not too difficult I think, can be done with inline phantom types for try and erro returns if not mistaken)

Anyway this is speculative.

We'll see.
(As far as I'm concerned, I like recognizable idioms so I'm rather fine with the statu quo on this issue. Perhaps that it would be useful in rare library code but all the more reason to keep that as a userland library)

@susugagalala
Copy link

@atdiar I notice a large portion of the counter-proposal #32825 were made during 2019. From 2019 till now, the results of the Go Developer Surveys have consistently shown one constant: the critical feature that the Go community want most is better error handling (after generics which has been implemented). So which is more representative of the Go community? Either the posts in #32825 do not represent the Go community at large, or there are sampling errors in the Go Developer Surveys?

Actually, it doesn't really matter which. I believe the Go team agrees that the error handling framework needs improvement; otherwise, #32437 would not have been proposed in the first place. I suggest that the Go team either "ask" those people again (in #32825 which was posted in 2019) whether they still believe in the status quo in light of the recent Developer Survey results, or have faith in the Developer Surveys and go ahead and take the lead in coming up with the initial error handling prototype. I honestly believe the latter path is the right thing to do if the Go team really believes that error handling in Go needs improvement.

@doggedOwl
Copy link

@gophun and yet error handling is consistently reported as one of the main problems in developer surveys. github issue votes attract a very strict subset of developers.

Unfortunetly as I have already commented on other issues related to this, this is something for which I doubt that a technical solution can be found. The two positions are "conceptual" ones and there's no bridging them.
Unless we forget the "one true way" and implement an alternative for the community that wants less visual noise without removing what currently is for the other part of the community. And as with the Generics solution, this soluton too does not need to be the best, but a good enough solution.

@gophun
Copy link

gophun commented Jun 8, 2024

The survey numbers do not contradict the community's preference for the status quo. If 30% want error handling to improve, but 70% absolutely want it to stay as it is, the 30% can still cause a high ranking in the developer surveys. The survey results were the reason the Go team took the initiative in 2019 and made the design proposals. After the first proposal, they spent months gathering feedback and experience reports, leading to the second, improved design, which received so much pushback and negativity from the community that the effort was abandoned.

With generics, the situation was different. Here, the surveys showed a high demand, and the community was also supportive of the design process.

@susugagalala
Copy link

@gophun

The survey numbers do not contradict the community's preference for the status quo. If 30% want error handling to improve, but 70% absolutely want it to stay as it is, the 30% can still cause a high ranking in the developer surveys. The survey results were the reason the Go team took the initiative in 2019 and made the design proposals. After the first proposal, they spent months gathering feedback and experience reports, leading to the second, improved design, which received so much pushback and negativity from the community that the effort was abandoned.

If what you wrote is the current reality, then the Go community should stop submitting any more error handling proposals as they will ultimately be rejected, isn't it? If that's the case, perhaps the forum moderator should state this clearly as such to save the time of Go programmers who are passionate about seeing Go improve. If, however, the Go team is waiting for a good error handling proposal to change this status quo, then all the more the Go team should consider taking the lead in coming up with the initial prototype because the "good proposal" might take years to appear (or never will).

@ianlancetaylor
Copy link
Contributor

We would be willing to consider a good error handling proposal that had good community support.

Unfortunately I'm sorry to say that essentially all new error handling proposals are not good and do not have community support. For example, this one has 10 thumbs down votes and no thumbs up votes. I would certainly encourage people to avoid filing error handling proposal until they have used the language extensively.

I would also encourage people to review earlier proposals. Here they are: https://github.com/golang/go/issues?q=label%3Aerror-handling+ . 183 and counting. I've read every single one myself. Importantly, bear in mind that a tweak on a rejected proposal will almost certainly also be rejected. And bear in mind that we are only going to accept a proposal that fits in well with the existing language. For example, this proposal, with its use of a magic @ symbol, is completely unlike anything else in the existing language.

The Go team may in due course make a new error handling proposal. However, it's quite true, as others have said, that our best ideas were considered unacceptable by the community. And there is a large number of Go programmers who are OK with the ways things are.

@xiaokentrl
Copy link
Author

在多行形式中,非零误差值是否有效地成为行的误差值?已经有几项具有类似特征的提案。很难处理声明。请注意,您不能使用范围内具有其他变量的标签,但这正是您的示例中发生的情况。goto``@``goto

Set ENV

ERROR_SINGLE = TRUE   //error_single = true

@xiaokentrl
Copy link
Author

Go 团队已经这样做了(两次),最后一次是 #32437。这是有史以来 Go 问题跟踪器上投反对票最多的提案。社区提案 #32825 对此进行了反驳,以保持错误处理不变。这是有史以来投票最多的 Go 提案。

Set ENV

ERROR_SINGLE = TRUE   //error_single = true

@xmonader
Copy link

I think maybe this could be a good option

func getData() (string, error) {
	txt, err := http.Get() orelse
	txt, err := http.Get() orelse error.Errorf("some error %w", err)
}

maybe the orelse could be named orbail to indicate the implicit return?
and if the the user want want more explicit they can do the regular if err != nil checks

@ianlancetaylor
Copy link
Contributor

@xmonader That is a different proposal that should be discussed elsewhere.

That said similar ideas have been proposed several times.

@xmonader
Copy link

@ianlancetaylor My bad, I'll review what been sent before and repost separately if I don't find it. thanks

@zhao6810
Copy link

func GetUser () error{

try {
	username,_ := GetUserName()
	level,_ := GetUserLevel()
	age,err := GetUserAge()

} catch (index,err){
	if (index == 1){
		fmt.Println("username error",err)
	}
	if (index == 2){
		fmt.Println("level error",err)
	}
}


if err != nil{
	fmt.Println("age error",err)
}

return nil

}

func GetUserName() (string,error) {
return "zhao6810",nil
}

func GetUserLevel () (int,error){
return 10,nil
}

func GetUserAge() (int,error){
return 18,nil
}

@ianlancetaylor ianlancetaylor changed the title proposal: Go 2: catch error model, a rethink of check/handle proposal: spec: catch error model, a rethink of check/handle 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 syntax is unlike anything else in Go. The 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 Oct 2, 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