Just an opinion, but I think the "err != nil" situation is good, because the whole premise is that your code must be readable. Other languages have much better ways of abstracting errors (eg try-catch in typescript) but Golang's boring, verbose syntax enforces readability. Even if you think "omg, this is too much", you and anyone else that knows Golang will immediately understand what you're guarding against. That said, there are situations where you repeat the same types of errors over and over again. For example, if something goes wrong during an http request, you may set a given status code, prepare a standardized JSON response, and maybe abort from the middleware. That's the kind of thing you may wanna abstract away into a helper function. It's used so often in your project that it makes sense. I would politely advise people to write the long syntax of err != nil, and once the repetition becomes obvious, refactor. It's easier than planning for abstractions that may never be needed. Good video! I like the first pattern, because you can implement that at the package level without increasing the Golang language footprint. The second one is fine, but the error handling is too abstract imo (talking about guard, in particular... but must might have similar issues, especially when you want to inject additional behavior during the error-handling process). The try() syntax isn't for me. I'll leave it there. Best wishes to everyone🏆
exactly! plus, these ideas don't explain what the program will do if a program encounters an error. does it automatically panic and abort? do we have some sort of error handler function to go along with these abstractions? at least with "err != nil" the flow of the program is very easy to understand, unlike these abstractions, and we have complete control over what happens
I agree. Go's simple error handling mechanism may seem long for your multiple lines of code, but at the same time, it allows programmers of any level to read and understand the flow of code. For me, if err!=nil{} block is one of the best error handling mechanisms I've ever come across in my career.
I actually think error handling is fine. It’s very readable and follows the logical path through the program. Out of these, I like check the most because it requires an error handler, which is a nice functionality.
If we need to do this, golang MUST introduces new keywords, otherwise, any nested return can not trigger the parent level return. The check() and try() seems nice, but they are still function, built-in function is still a function, it has to follow the rules
I don't like the proposed solutions because of how they hide (or make implicit) the actual return values. Even so, the 'check' function seems least inelegant out of the other proposals. However, one could easily implement that at the package level, if one so wishes.
and there's no wrapping / decoration for the error, such as `fmt.Errorf("while doing stuff: %w", err)`. Implementing "check" on package level won't make it possible to return an error directly.
I personally really like the 'try' proposal. But making 'try' necessarily a function call will probably hurt readability, because you don't expect that type of control flow gymnastics from simple function calls (one of the reasons why panic is problematic). The brackets are better left optional imo (the way range works)
I just started learning Go, but I also thought this one looked the easiest to me. I really don't have a problem with the way it is, but if it can be made better.
One step to fixing error handling is to introduce null safety. The first time I made a nil issue, I almost ran mad since the error was not clear where it occurred nor could I see it in the code.
i personally don't feel any bad with current error handling, for me it encourages me to write perfect code that guarantees to run without any problem. among these proposals I think try catch is better. with catch there would be an extra explicit way to handle error.
Error handling is perfect as is. It is the reason why Go production software is so stable. You must do the tedious but very important job that other languages allow you to ignore.
I would prefer if they focused on requiring an interface/type system for errors so calling code is able to know the different types of error they are possible, plus the compiler can force the caller to account for them
100% Agree, having implemented a wrapper around the current error so in that my errors contain more informative information. Doing allowed code to execute better on what type of error had been dealt.
What is wrong with everyone saying error handling in Go is fine? Are you crazy? You have to deal with errors everywhere for everything and if you hit one in your program you don't know where it came from if functions calls are chained together in the slightest manner. This is the point of the stack trace in other languages, Go is a huge step backwards in terms of errors. If they fix error handling everyone who likes dealing with errors every 5 or 10 lines of code can continue to do so, I'm sure. if err != nil have fun!
> You have to deal with errors everywhere for everything Yes, that's why it's fine, you have to deal with them. What's the alternative? Crash with a backtrace or wrap everything between try..catch? > you don't know where it came from if functions calls are chained together in the slightest manner You do if you wrap them properly, `if err != nil { return fmt.Errorf("load configuration: %w", err) }`. You will end up with errors like "failed to start server: load configuration: open xyz.txt: no such file" > This is the point of the stack trace in other languages Go errors are failure indicators, not errors in your code. You get a stack trace in go too when an unhandled error happens.
Ruby supports inverted conditionals, which works -great- with error handling. "return nil, err if err" would be elegant and still be within the current go patterns
I think Go should use Exceptions like Java, C++, and Python has. This seems so easy to work with: try { func_one() func_two() func_three() func_four() } catch(exception) { fmt.Println("Exception detected: " + exception) } Exceptions allows for the separation of error handling from program logic.
After studying panic(), recover(), and defer I decided that exceptions are no longer needed. panic() and recover() can be used very similarly to exceptions.
I personally like to write every single line of code and in error handling I can use logic to do certain things. I like the simplicity of the error handling, and to me I don't like any of the proposals.
I think the same. The reason for use go is its simplicity, and speed. My fear is to add a bunch of keywords and turn go into some other language which allow the dev to do a lot of things, which in counter part, causes a lot of issues.
The check you are still writing the handling code, you are just putting it in one place which is good if you want to handle the same way multiple times.
I'd go for the third solution because it's nice and clean. However, it adds a layer of abstraction. To get rid of the ugly ifs, I use a selfmade package with some wrapper functions to handle errors like e.g. errors.Fatal(err). It isn't usable in all situations, but it makes the code clean, and remains readable.
It's not only ugly but redundant. Imagine you have to handle error handling for files in 10 different places and then you suddenly decide to change the way it's handled. To do so, you gotta move to 10 different places and edit them one by one. Sure, you can take help from your IDE, but your code still gets redundant in 10 different places, which can be avoided by just wrapper with an error handling function.
Not a fan of the proposed solutions. The current process can be improved upon, but these other solutions are too convoluted. Thank you for the great content though!!!
And not a single word about the real problems. The main problem with the errors package is that you cannot hide several private errors behind one more abstract one and check any error from the chain (as with exceptions). For %w, you can hide only one error. That is, the correct way to handle an error from a function now will be to catch a huge bunch of small errors at the lowest level from each nested function. Or you can leave only the topmost error with the loss of the previous context.
Current design pattern is the best. You'd love it if you ever try to debug you own or other's code. Everyone will follow the same style so there would be no problem to understand what the code does. The proposals are good when you're writing code to forget about maintaining it later.
for almost three years i'm a java developer and i hate exception handling with try cache. I hope one time i can switch to go and work with if err !=nil :D
To be honest, not sure if this is a real concern. There's a lot of reason to keep the error pattern, but if someone really think it's best to hide it, they could just do something like func Must[T any](v T, err Error) T { if err != nil { panic(err) } return v } // out := Must(funcWIthError()) then, just create a decorator, wrapping it with a defer and use recover() do define some behavior. AGAIN, I really don't like such approaches like this, I really don't think that we should "hide" the actual code. Less code not necessarily means "that's a good one"
How about importing some constructs from Erlang and Elixir? Why not do the `with` construct from Elixir? Ex: with dob blabla end Of course this requires pattern matching Another easy implementation would be Go would implement functions with multiple definitions to remove all those if then else structures. But this also requires pattern matching... There are also other neat possibilities, but the constructs in Go don't make it possible. I just started learning Go because I became frustrated with a few things in Elixir and wanted easier command line apps & cross compilation. But looking at Go, there are some things which make me reconsider if I'm going to switch. Error handling is one of them.
Since "and" and "or" are not keywords in go currently, how about: foo, err := tryStuff() or return "", fmt.Errorf("while trying stuff: %w", err) err := f.Close() and log.Debugf("closed %s", f.Name()) I guess, to make it more readable, you could write it like: foo, err := tryStuff() or return "", fmt.Errorf("while trying stuff: %w", err)
The hard part is to stay backwards compatible, with all the if err!= null out there. If Golang add a new way of handling error, there will be two: The current one with if err! =nil and the new one. I personally like the error handling in rust with Result, expect, Unwrap... and I believe that Go can do the same without too much efforts
I like the try proposal, but the handler from the check proposal should be included as an optional second argument. If only one argument is provided it returns err. Equivalent to an uncaught exception. If second argument is provided, it uses it as the handler. This is like a catch statement. You could also make the second argument optionally a string for returning a custom error message. But having thought about it, idk if we really need a built in function since it’s easy to write your own.
I have yet to find a better error handling solution than rust. The Results enum is an amazing concept. I like to think of it as a smart tuple you have to handle correctly. Python exceptions are second to rust enums IMO. I personally hate the c style if check after functions.
rust's error handling is taken out of Haskell and similar languages where you have Maybe (Option) and Either (Result). This way of handling errors is amazing but for Go going the Zig route is probably better since both handle errors as normal values instead of sum types
@@FlanPoirot I have yet to look into zig, it's next on my list after rust and go. I don't see zig taking off though, this is purely based on feelings and no facts.
@@ic3man5 zig has been gaining a lot of ground (relatively) and it's not even 1.0 yet, idk if zig will catch on, but the general trend for it seems upwards and it has gained way more traction and hype than other similar languages, zig is a really nice language and I think there might be a niche for it. Even if it doesn't catch on, it's a simple language and takes a few hours tops to learn (way less than rust), so I think it's worth a try at least and u can see how it solves null with control flow and errors with union types and comptime is a killer feature (replacing many features like macros, templates and generics at once)
@@FlanPoirot they need to be able to do embedded to displace C before it will ever be taken seriously. What you said sounds promising, will look into it for sure.
I don't see a big difference between go and rust error handling. Rust returns a value that holds two values, go returns two values. The only practical difference is the "try!" macro in rust, which is essentially just a shorter way to write `if err != nil { panic(err) }`.
My main gripe with error handling in Go is the lack of a hierarchy of errors, typically what you'll have when dealing with checked exceptions. From time to time I have to use strings.Contains() against err.Error() and I die a bit inside. Someting like if err is error.IoError would have been nice. This isn't something you can retrofit into a language / stdlib. So we're stuck with what we've got. I'll live.
@@rameninspace7182 Yes. But even the standard library doesn't really have error types for a lot of the errors. Say I'm doing io.Copy(). The docs say nothing about what errors it will return. Looking at the source of io.Copy most of the errors aren't even exported. So you're left with doing string matching on err.Error(), not really great.
Then go would also need exceptions and a way to "throw" them. And then you would need to always handle the exceptions. When you do something like "result := Add(1, 2)" you really must know what that function and the functions it uses do internally to find out if it may throw something. From Go FAQ: > Why does Go not have exceptions? > We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional.
From Go FAQ: > Why does Go not have exceptions? > We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional.
The way Golang deals with errors is fine! If you don't feel ok with it, implement your own package/helper/whatever to deal with error type! Don't turn the simplicity of Golang a mess, don't try to compare or to make golang like the other languages!
I am newbie to golang. But i can see a potential issue with your proposal. I might be wrong, but in golang we cant create brand new statements in packages, so it has to be some sort of a function. If i want to return from the function when a function errors out, i cant just call another function to do the job for me. In C and C++, we could write macros to do this repetitive inplace replaces. But unfortunately go doesnt allow that too.
Go has no error handling. Just because ppl who use the language tend to follow an error handling convention doesn't mean the language supports error handling. If you don't agree, then every modern language has Go's error handling. In java you wrap your return values in objects that can have an error object inside them.
So it’s just proposals only, which is no idea when it’s going to be added or even accepted 😁 I’d rather you make a video on how to handle those with a current versions of go
4th proposal: all function calls are checked for errors by a new built-in Go feature. When an error occurs an error function is called by an index to differentiate between errors, and additionally an error message. Developer may overwrite the error function to customize what to do on different cases.
error handling is the most annoying part of golang.. none of the proposal look any solid.. they simply should introduce algebraic data type for error handling..
I don't like check because it requires writing error handler before calling a function which is illogical. `guard` is a nice keyword. panic on error is not so common, so I would not add syntax sugar for that.
The second solution looks good, but it will turn out to be a disaster. Personally i find that as i am learning golang, the things that frustate me the most, are places where the language is trying to extra clever just for laughs. Guard trying to return 0 values for other arguments except the error argument sounds very similar. I dont know how it can go wrong, but it sounds like the things that are frustating me in go already.
Agree with all your points, mainly all of this could be improved in the early days of the language but at that time (and also somehow still today) the arrogance of maintainers against important requested language features that will probably available in Go 2 make a lot of consideration to now don't end breaking old code compatibility, Go is a great language but sadly some features are extremely bad designed like error handling as you say, also a pain that apparently there is not interest to fix by the maintainers but hope you make a video about is the C code call performance issue, the performance bottleneck (extremally important in Real time monitoring applications) when Go calls C functions makes the language last choice for those scenarios and the lack of compile time C types manipulations force the language to not end being used when vendor C libraries are needed
I don't like just returning the error. On each step I would like to add some context info to my error message about current function doing fmt.Errorf("context: %v", err) so in the end I'll have a very nice error message with a long path and context about each step. Only first solution can allow me to do it but it will require to write a lot of different exist functions that is not nice
if err != nil I think is good cause it's simple and readable if someone have python or java experience they would agree with ideas that it's very very simple than in other language Golang have dirty solution but simple and effective and I think golfing don't need new way of handling errors
I feel that we need to have a better way to do it smaller than create new structures or utils functions. It's good to have everything explicit, the problem is that it create a LOT of additional lines, maybe a good way is to support ternary statements to do it in one line. But not a try catch.
I think the error handling is not something to fix honestly. In my opinion, I like the way of current error handling does in Go, I like the verbosity and even we can check error type, which is great
#3 seems pointless. The zero return would still end up needing to be checked by the app code. I would say #1 would be OK, especially if combined with an anonymous function
Honestly, all they need to add is an operator for error which only assigns a value its currently nil: value, err := someFunction() value2, err? := someOtherFunction() // will only return nil if both functions return nil for err if (err != nil) {...}
The current error-hanling pattern is good enough. It's hard to see that Go is slightly going to Java side 😔 "Explicit is better than implicit" (c) PEP20
It could be done your own abstraction or error handler of each module? Or a principal module(Generics) handling the bare-bone of errors and importing in other modules to implement the specifics
Looks very similar to me, except the tutorial encourages the use of panic and there's the "try!" macro which is just syntax sugar for doing `if err != nil { return nil }`.
go[.dev]/blog/survey2020-results (remove square brackets, added cause yt delete comment) Second chart in "Pain points" section Better late than never :)
isn't the third and second proposal the same? And I don't like them, the main problems with errors is the boilerplate but that drive us to another more important problem: being lazy in error handling, and the second and third proposal are the best way to increase lazy error handling I think the first proposal can be improved even add syntactic sugar and it would be a good addition
Get your FREE Golang Cheat Sheet -
golangdojo.com/cheatsheet
Rust syntax with question mark? :)
```
file := os.Open("foo.txt")?
```
Just an opinion, but I think the "err != nil" situation is good, because the whole premise is that your code must be readable. Other languages have much better ways of abstracting errors (eg try-catch in typescript) but Golang's boring, verbose syntax enforces readability. Even if you think "omg, this is too much", you and anyone else that knows Golang will immediately understand what you're guarding against. That said, there are situations where you repeat the same types of errors over and over again. For example, if something goes wrong during an http request, you may set a given status code, prepare a standardized JSON response, and maybe abort from the middleware. That's the kind of thing you may wanna abstract away into a helper function. It's used so often in your project that it makes sense. I would politely advise people to write the long syntax of err != nil, and once the repetition becomes obvious, refactor. It's easier than planning for abstractions that may never be needed. Good video! I like the first pattern, because you can implement that at the package level without increasing the Golang language footprint. The second one is fine, but the error handling is too abstract imo (talking about guard, in particular... but must might have similar issues, especially when you want to inject additional behavior during the error-handling process). The try() syntax isn't for me. I'll leave it there. Best wishes to everyone🏆
exactly! plus, these ideas don't explain what the program will do if a program encounters an error. does it automatically panic and abort? do we have some sort of error handler function to go along with these abstractions? at least with "err != nil" the flow of the program is very easy to understand, unlike these abstractions, and we have complete control over what happens
I agree. Go's simple error handling mechanism may seem long for your multiple lines of code, but at the same time, it allows programmers of any level to read and understand the flow of code.
For me, if err!=nil{} block is one of the best error handling mechanisms I've ever come across in my career.
I actually think error handling is fine. It’s very readable and follows the logical path through the program. Out of these, I like check the most because it requires an error handler, which is a nice functionality.
Currently, I work in JS and I follow the same mechanism that Go has. Like you said - It's readable and follows the logical path.
I agree, but it can definitely be somewhat better. Some types of sugar aren't all that bad e.g., switch statements in Go.
@@raianmr2843 I think check is pretty nice, as I kind of do this anyway, just usually in a block
Now imagine having to write that 1000 times...
Same with this I will choose it over try catch anytime.
If we need to do this, golang MUST introduces new keywords, otherwise, any nested return can not trigger the parent level return. The check() and try() seems nice, but they are still function, built-in function is still a function, it has to follow the rules
I don't like the proposed solutions because of how they hide (or make implicit) the actual return values. Even so, the 'check' function seems least inelegant out of the other proposals. However, one could easily implement that at the package level, if one so wishes.
and there's no wrapping / decoration for the error, such as `fmt.Errorf("while doing stuff: %w", err)`. Implementing "check" on package level won't make it possible to return an error directly.
I personally really like the 'try' proposal. But making 'try' necessarily a function call will probably hurt readability, because you don't expect that type of control flow gymnastics from simple function calls (one of the reasons why panic is problematic). The brackets are better left optional imo (the way range works)
Agreed allowing a simple return call to be on one line after the check would hugely simplify the code
I just started learning Go, but I also thought this one looked the easiest to me. I really don't have a problem with the way it is, but if it can be made better.
One step to fixing error handling is to introduce null safety.
The first time I made a nil issue, I almost ran mad since the error was not clear where it occurred nor could I see it in the code.
yes, that's why i print message before returning error so I could pinpoint where the issue came from
i personally don't feel any bad with current error handling, for me it encourages me to write perfect code that guarantees to run without any problem. among these proposals I think try catch is better. with catch there would be an extra explicit way to handle error.
How does having to write the same piece of code over and over encourage you to write "perfect code"?
lol what? maybe you should start to use other language to see how bad golang error handling is.. is on epic scale of bad
@@Asdasxel ikr.. funny.. maybe they haven't try to write programming in other language i guess..
@@Asdasxel What's the alternative? Writing everything inside try..catch or let the app crash? Is "file not found" an exception?
Error handling is perfect as is. It is the reason why Go production software is so stable. You must do the tedious but very important job that other languages allow you to ignore.
I would prefer if they focused on requiring an interface/type system for errors so calling code is able to know the different types of error they are possible, plus the compiler can force the caller to account for them
100% Agree, having implemented a wrapper around the current error so in that my errors contain more informative information. Doing allowed code to execute better on what type of error had been dealt.
agree 100%
Golang needs a better string interpolation, the actual is annoying.
What is wrong with everyone saying error handling in Go is fine? Are you crazy? You have to deal with errors everywhere for everything and if you hit one in your program you don't know where it came from if functions calls are chained together in the slightest manner. This is the point of the stack trace in other languages, Go is a huge step backwards in terms of errors. If they fix error handling everyone who likes dealing with errors every 5 or 10 lines of code can continue to do so, I'm sure. if err != nil have fun!
> You have to deal with errors everywhere for everything
Yes, that's why it's fine, you have to deal with them. What's the alternative? Crash with a backtrace or wrap everything between try..catch?
> you don't know where it came from if functions calls are chained together in the slightest manner
You do if you wrap them properly, `if err != nil { return fmt.Errorf("load configuration: %w", err) }`. You will end up with errors like "failed to start server: load configuration: open xyz.txt: no such file"
> This is the point of the stack trace in other languages
Go errors are failure indicators, not errors in your code. You get a stack trace in go too when an unhandled error happens.
Ruby supports inverted conditionals, which works -great- with error handling.
"return nil, err if err" would be elegant and still be within the current go patterns
+1
I think its over complicated, I dont think adding another layer of abstraction for errors is a good thing.
Go: generics is ready!!
Me: still not using it...
if they change "guard" to "should" #2 gets my vote
I think Go should use Exceptions like Java, C++, and Python has. This seems so easy to work with:
try {
func_one()
func_two()
func_three()
func_four()
}
catch(exception) {
fmt.Println("Exception detected: " + exception)
}
Exceptions allows for the separation of error handling from program logic.
After studying panic(), recover(), and defer I decided that exceptions are no longer needed. panic() and recover() can be used very similarly to exceptions.
How about the lack of stack traces? What to do if some third-party libraries outside my control emit errors without stack traces attached to them?
No God, Please No! Its not broken. Please don't fix it!
In my opinion the best solution for error handling is to use exceptions (try/catch/finally/stack trace). There is no need to reinvent the wheel.
It's a bad wheel.
Totally agree, having come from C++, I find Go lacking in so many things that are very useful.
I personally like to write every single line of code and in error handling I can use logic to do certain things. I like the simplicity of the error handling, and to me I don't like any of the proposals.
I think the same. The reason for use go is its simplicity, and speed. My fear is to add a bunch of keywords and turn go into some other language which allow the dev to do a lot of things, which in counter part, causes a lot of issues.
The check you are still writing the handling code, you are just putting it in one place which is good if you want to handle the same way multiple times.
I'd go for the third solution because it's nice and clean. However, it adds a layer of abstraction. To get rid of the ugly ifs, I use a selfmade package with some wrapper functions to handle errors like e.g. errors.Fatal(err). It isn't usable in all situations, but it makes the code clean, and remains readable.
It's not only ugly but redundant. Imagine you have to handle error handling for files in 10 different places and then you suddenly decide to change the way it's handled. To do so, you gotta move to 10 different places and edit them one by one. Sure, you can take help from your IDE, but your code still gets redundant in 10 different places, which can be avoided by just wrapper with an error handling function.
Not a fan of the proposed solutions. The current process can be improved upon, but these other solutions are too convoluted. Thank you for the great content though!!!
I like the current way how go handles errors. It's simple and straight forward
And not a single word about the real problems. The main problem with the errors package is that you cannot hide several private errors behind one more abstract one and check any error from the chain (as with exceptions). For %w, you can hide only one error. That is, the correct way to handle an error from a function now will be to catch a huge bunch of small errors at the lowest level from each nested function. Or you can leave only the topmost error with the loss of the previous context.
You can always write 'small errors' in a log file and developers should do that anyway.😉
Current design pattern is the best. You'd love it if you ever try to debug you own or other's code. Everyone will follow the same style so there would be no problem to understand what the code does.
The proposals are good when you're writing code to forget about maintaining it later.
i choose classical error handling :)
We always welcome new Gophers with "If err != nil {}" construct 😄
for almost three years i'm a java developer and i hate exception handling with try cache. I hope one time i can switch to go and work with if err !=nil :D
To be honest, not sure if this is a real concern.
There's a lot of reason to keep the error pattern, but if someone really think it's best to hide it, they could just do something like
func Must[T any](v T, err Error) T {
if err != nil { panic(err) }
return v
}
// out := Must(funcWIthError())
then, just create a decorator, wrapping it with a defer and use recover() do define some behavior.
AGAIN, I really don't like such approaches like this, I really don't think that we should "hide" the actual code.
Less code not necessarily means "that's a good one"
How about importing some constructs from Erlang and Elixir?
Why not do the `with` construct from Elixir?
Ex:
with dob blabla
end
Of course this requires pattern matching
Another easy implementation would be Go would implement functions with multiple definitions to remove all those if then else structures. But this also requires pattern matching...
There are also other neat possibilities, but the constructs in Go don't make it possible.
I just started learning Go because I became frustrated with a few things in Elixir and wanted easier command line apps & cross compilation. But looking at Go, there are some things which make me reconsider if I'm going to switch. Error handling is one of them.
Since "and" and "or" are not keywords in go currently, how about:
foo, err := tryStuff() or return "", fmt.Errorf("while trying stuff: %w", err)
err := f.Close() and log.Debugf("closed %s", f.Name())
I guess, to make it more readable, you could write it like:
foo, err := tryStuff()
or return "", fmt.Errorf("while trying stuff: %w", err)
The hard part is to stay backwards compatible, with all the if err!= null out there. If Golang add a new way of handling error, there will be two: The current one with if err! =nil and the new one. I personally like the error handling in rust with Result, expect, Unwrap... and I believe that Go can do the same without too much efforts
I like the try proposal, but the handler from the check proposal should be included as an optional second argument.
If only one argument is provided it returns err. Equivalent to an uncaught exception.
If second argument is provided, it uses it as the handler. This is like a catch statement. You could also make the second argument optionally a string for returning a custom error message.
But having thought about it, idk if we really need a built in function since it’s easy to write your own.
Current error handling is very intuitive for me, I'll continue using it
I have yet to find a better error handling solution than rust. The Results enum is an amazing concept. I like to think of it as a smart tuple you have to handle correctly. Python exceptions are second to rust enums IMO. I personally hate the c style if check after functions.
rust's error handling is taken out of Haskell and similar languages where you have Maybe (Option) and Either (Result). This way of handling errors is amazing but for Go going the Zig route is probably better since both handle errors as normal values instead of sum types
@@FlanPoirot I have yet to look into zig, it's next on my list after rust and go. I don't see zig taking off though, this is purely based on feelings and no facts.
@@ic3man5 zig has been gaining a lot of ground (relatively) and it's not even 1.0 yet, idk if zig will catch on, but the general trend for it seems upwards and it has gained way more traction and hype than other similar languages, zig is a really nice language and I think there might be a niche for it. Even if it doesn't catch on, it's a simple language and takes a few hours tops to learn (way less than rust), so I think it's worth a try at least and u can see how it solves null with control flow and errors with union types and comptime is a killer feature (replacing many features like macros, templates and generics at once)
@@FlanPoirot they need to be able to do embedded to displace C before it will ever be taken seriously. What you said sounds promising, will look into it for sure.
I don't see a big difference between go and rust error handling. Rust returns a value that holds two values, go returns two values. The only practical difference is the "try!" macro in rust, which is essentially just a shorter way to write `if err != nil { panic(err) }`.
I usually write a checkError(err) function to handle these.. easy and simple.
My main gripe with error handling in Go is the lack of a hierarchy of errors, typically what you'll have when dealing with checked exceptions. From time to time I have to use strings.Contains() against err.Error() and I die a bit inside. Someting like if err is error.IoError would have been nice.
This isn't something you can retrofit into a language / stdlib. So we're stuck with what we've got. I'll live.
You can use errors.Is or if you want to type check it you can use errors.As
@@rameninspace7182 Yes. But even the standard library doesn't really have error types for a lot of the errors.
Say I'm doing io.Copy(). The docs say nothing about what errors it will return. Looking at the source of io.Copy most of the errors aren't even exported.
So you're left with doing string matching on err.Error(), not really great.
why do they not just implement, try {} catch(){} ???
Then go would also need exceptions and a way to "throw" them. And then you would need to always handle the exceptions. When you do something like "result := Add(1, 2)" you really must know what that function and the functions it uses do internally to find out if it may throw something.
From Go FAQ:
> Why does Go not have exceptions?
> We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional.
Why can't we just impleement try & catch block like other languages ?
From Go FAQ:
> Why does Go not have exceptions?
> We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional.
The way Golang deals with errors is fine! If you don't feel ok with it, implement your own package/helper/whatever to deal with error type! Don't turn the simplicity of Golang a mess, don't try to compare or to make golang like the other languages!
I am newbie to golang. But i can see a potential issue with your proposal. I might be wrong, but in golang we cant create brand new statements in packages, so it has to be some sort of a function. If i want to return from the function when a function errors out, i cant just call another function to do the job for me.
In C and C++, we could write macros to do this repetitive inplace replaces. But unfortunately go doesnt allow that too.
It always amazes me to see the amount of effort people will expend to avoid a small amount of effort.
"Generics finally added"
Me: "I have 0 idea what that even is"
Go has no error handling. Just because ppl who use the language tend to follow an error handling convention doesn't mean the language supports error handling. If you don't agree, then every modern language has Go's error handling. In java you wrap your return values in objects that can have an error object inside them.
the try proposal wins, and it's easy to understand if you are already familiar with try in other languages
Errors are values. Go proverb.
This is not going to change. And I love it.
So it’s just proposals only, which is no idea when it’s going to be added or even accepted 😁 I’d rather you make a video on how to handle those with a current versions of go
you have to add all the if statements lol, that's why it was top on the list of things needing fixing
I like guard and must. Well, This is the video that posted in 5 months ago, I don't think the core team would accept any of these proposals.
4th proposal: all function calls are checked for errors by a new built-in Go feature. When an error occurs an error function is called by an index to differentiate between errors, and additionally an error message. Developer may overwrite the error function to customize what to do on different cases.
Go team got to accept one of those proposals or come up with their own. At least for now, they can put error handling functions in a built-in library.
Implement pipes? - any part of the pipe that returns an error short circuits the rest of the pipe and then handle the error.
I prefer the Rust way to handle error handling.
Check how error handling is implemented in Elixir: 'with' keyword that can handle a pipeline of responses with potential errors.
error handling is the most annoying part of golang.. none of the proposal look any solid.. they simply should introduce algebraic data type for error handling..
I don't like check because it requires writing error handler before calling a function which is illogical.
`guard` is a nice keyword. panic on error is not so common, so I would not add syntax sugar for that.
The second solution looks good, but it will turn out to be a disaster. Personally i find that as i am learning golang, the things that frustate me the most, are places where the language is trying to extra clever just for laughs. Guard trying to return 0 values for other arguments except the error argument sounds very similar. I dont know how it can go wrong, but it sounds like the things that are frustating me in go already.
Agree with all your points, mainly all of this could be improved in the early days of the language but at that time (and also somehow still today) the arrogance of maintainers against important requested language features that will probably available in Go 2 make a lot of consideration to now don't end breaking old code compatibility, Go is a great language but sadly some features are extremely bad designed like error handling as you say, also a pain that apparently there is not interest to fix by the maintainers but hope you make a video about is the C code call performance issue, the performance bottleneck (extremally important in Real time monitoring applications) when Go calls C functions makes the language last choice for those scenarios and the lack of compile time C types manipulations force the language to not end being used when vendor C libraries are needed
I don't like just returning the error. On each step I would like to add some context info to my error message about current function doing fmt.Errorf("context: %v", err) so in the end I'll have a very nice error message with a long path and context about each step. Only first solution can allow me to do it but it will require to write a lot of different exist functions that is not nice
if err != nil I think is good cause it's simple and readable
if someone have python or java experience they would agree with ideas that it's very very simple than in other language
Golang have dirty solution but simple and effective
and I think golfing don't need new way of handling errors
So we're not gonna have any proper monadic error handling?
"must" method is interesting
I like the second proposal
I feel that we need to have a better way to do it smaller than create new structures or utils functions. It's good to have everything explicit, the problem is that it create a LOT of additional lines, maybe a good way is to support ternary statements to do it in one line. But not a try catch.
how to use it? i try to type catch, try or other, but it "undefined". Sorry, iam new learn golang, and i confuse about it
"Here's how to fix it"... then proceeds to show unimplemented high level proposals.
I think the error handling is not something to fix honestly. In my opinion, I like the way of current error handling does in Go, I like the verbosity and even we can check error type, which is great
we need a better error handling of course, and I think the try keyword would be a nice solution.
I love how 4:29 there's more code lol
#3 seems pointless. The zero return would still end up needing to be checked by the app code. I would say #1 would be OK, especially if combined with an anonymous function
What’s the current status?
In other langs errors are classes. Just create an interface for them.
I like go error handling, it's very simple and does the job without introducing new concepts
I tried multiple times with multiple email accounts to get free cheatsheet but I received no email.
Honestly, all they need to add is an operator for error which only assigns a value its currently nil:
value, err := someFunction()
value2, err? := someOtherFunction() // will only return nil if both functions return nil for err
if (err != nil) {...}
Still better than exceptions
if err is a feature not a bug
could you not implement something like the "try" proposal as a function right now?
The current error-hanling pattern is good enough. It's hard to see that Go is slightly going to Java side 😔 "Explicit is better than implicit" (c) PEP20
I like go's error handling
It could be done your own abstraction or error handler of each module? Or a principal module(Generics) handling the bare-bone of errors and importing in other modules to implement the specifics
I think they dropped the try proposal for Go 2
In the example at 4:53 how would the return statement inside the exit function cause the GetDivisor funcition to return?
explicit errors are good. What else language has it?
You're only 50% good if you do not provide the proposals links in the description. Why do you want to be 50% good only? Why not 100%?
Less abstraction is better.
Ok error handling rust is light-years ahead
Looks very similar to me, except the tutorial encourages the use of panic and there's the "try!" macro which is just syntax sugar for doing `if err != nil { return nil }`.
How is the market for go?
Looks like the go community is trying to fix go error handling with dialects of try catch lol
Hard to say, option 3 sounds OK. Most of the time, I'm doing log.Fatalln(err) and try might be good for basic error handle.
this, crying in nodeJS, my nodeJS brain fckd hahaha... anyway that's why i am on fire with go.
What is the graph's source in 0:40? Can you provide it please?
go[.dev]/blog/survey2020-results
(remove square brackets, added cause yt delete comment)
Second chart in "Pain points" section
Better late than never :)
Testing is shit too
Errors package good thou
I think insted of changing error handling in these ways, macros should be added allowing the user to implement syntatical suger like that
isn't the third and second proposal the same? And I don't like them, the main problems with errors is the boilerplate but that drive us to another more important problem: being lazy in error handling, and the second and third proposal are the best way to increase lazy error handling
I think the first proposal can be improved even add syntactic sugar and it would be a good addition
no, it's not
nice explain :)
They are horrible
Go error handling may be trash, but it's still better than any other language I've ever used
Thief Golang Dojo sell course and after remove platform with our money!