5 ms·
The programmer needs to be aware that they will need to provide enough context in case of a failure. One thing I see a lot in Go examples is this pattern: bo
by tail_exchange 3y ago
The programmer needs to be aware that they will need to provide enough context in case of a failure. One thing I see a lot in Go examples is this pattern:
body, err := readFile(fileName)
if err != nil {
return "", err
}
If the error returned by readFile is just "not found", it would indeed be very vague. This is still poor error handling, in my opinion, since a lot of the context is lost. Yes, they are "handling" the error, but only enough to stop the linter from complaining. I prefer something like this:
body, err := readFile(fileName)
if err != nil {
return "", errors.Wrapf(err, "readFile(%s)", fileName)
}
This would result inan error like this:
readFile(file.txt): not found
This way I get all the context I need to know where the error happened and the arguments that caused the error.
If the error happened not because of a function call, but, say, an invalid value, instead of this:
if n < 10 {
return fmt.Error("invalid argument")
}
Do this:
if n < 10 {
return fmt.Errorf("invalid argument n=%d is less than 10", n)
}
In languages like Java, it feels very tempting to let errors bubble up and then let the stack trace take care of explaining what went wrong, but it is often insufficient and may result in hours of debugging. I feel like Go makes it very easy to add extra context to errors, and if you foster the practice of adding context every time you return an errlr, it will be much richer than a stack trace.
- za3faran 3y agoYou basically end up reinventing stack traces, with all the possible ways context can be missed. This summarizes the language quite well.
- kitd 3y agoIME, it's stack traces that miss all the context. So an error occurred 20 levels down? What was it doing? With what?
- za3faran 3y agoYou can see the path that was taken to get to those 20 levels. Without stack traces, you're left to manually peruse the code base to figure all those out.
- preseinger 3y agostack traces are tools for developers, error messages are tools for users users should not see stack traces
- simiones 3y agoGo error messages are very much also tools for developers, if they are useful in any way.
- preseinger 3y agotrue! of course.
- simiones 3y agoI'm not sure we are in full agreement, my statement was a little ambiguous. I meant to say that, just like stack traces, Go error messages are only helpful to developers, at least 99.9% of the time. More generally, user error messages and dev error messages are just fundamentally at odds, there is no way to have messages that are good for both cases. User error messages should explain what went wrong, and what they can do differently to workaround the issue (if anything). Dev error messages should explain what the code was doing when something went wrong, to help with figuring out what code needs to be modified.
- preseinger 3y agonah go error messages are clear to users without being cryptic
- simiones 3y agoHow is an error like "Error in foo(): error in bar(): reading abcd.xml: file not found" clear to a user? What do foo() and bar() mean to them? What should they do about this missing file? This is just a more simply formatted stack trace, just as useless to an end user. The proper error message for a user in this situation would be something like "Couldn't read required file /home/user/program-name/abcd.xml. Please try to create the file by hand." or "Couldn't read list of entities. Try reinstalling the program or contact support@program-name.com".