Hi,

There are two kinds of errors: user-facing error and developer-facing 
error. User-facing error is an error that is supposed to be relayed back to 
the end-users. It is usually stripped from sensitive information and is 
generally more verbose. On the other hand, developer-facing error are 
intended for developers. It may contain stacktraces, etc. and is generaly 
more terse.

Go's standard error implementation is very basic and unassuming about your 
intended use. However, it is also trivial to write your own error library 
(Hint: the runtime package). I usually use my own error library. So 
whenever you find that the standard error implementation does not suit your 
need, feel free to implement your own.

In addition, in designing your functions, be sure to return error 
judiciously. Consider whether returning errors provide any value to the 
callers of your functions, and whether it is sufficient to just return a 
neutral value or to panic. In general, functions that return errors are 
more difficult to use. It is easy to 'pass the buck' and just blindly send 
back any error to the caller. In the end, at the top layer of the 
application, you end up with way too many error checking code. So, return 
error judiciously.

Some people think that using exceptions will help solve this problem. 
Exceptions merely hide the symptoms (eg. fewer error checking code), but it 
doesn't cure the problem, which is a poorly designed function interface. In 
fact, exceptions carry with them their own horde of problems. You have 
checked and unchecked exceptions. Some people prefer one to the other. Java 
has both, while the C# team considers checked exceptions does not bring any 
value to their existing problems. Then, you have versioning and scalability 
issue, etc.

Go's error handling is not perfect, but it is simple and thus any 
associated problems surrounding it are also easy to understand. 

On Monday, October 8, 2018 at 5:38:09 PM UTC+7, Chris Hopkins wrote:
>
> Hi,
> Could I please check what current error handling best practice is?
> I've gotten quite smitten with github.com/pkg/errors. I really like the 
> ability to create a stack of errors that trace to what is going on. However 
> it seems this is not an often used package - it's not available in 
> playground for example. It's really useful for diagnostics to see a stack 
> of what is causing an error, however in my latest application where I'm 
> trying to be really rigorous with my error handling I've hit - for want of 
> a better word - an imperfection. Could I check if there's a better way to 
> do these things:
> So here's what I'm doing:
> When I have an error I need to report I create it like this:
> var ErrInvalidVariable = errors.New("Invalid Variable")
> Which means that you can have code that nicely reads: 
> if err == ErrInvalidVariable { /* handle this error */}
> It's how the os package reports errors (along with helper functions), so I 
> assume this is the correct way.
>
>
> For better debug I can use errors.Wrap to annotate this error through the 
> error stack and get useful diagnostic printouts such as
> Line Processing passed "if $BOB==3": Token Passed $BOB : Invalid Variable.
>
> So far so good. This starts to fail though if I'm trying to determine lets 
> say a fileio error that came from the config file reader, vs the script 
> file reader. At the moment I can say
> _, err := os.Open(...)
> if err != nil {
>   return errors.Wrap(err, "Config File read error")
> }
> But without searching through the error text I can't tell who caused that.
> Now I could declare a specific type for this, add a Cause handler onto 
> that, but it starts to get clunky to do that for every error condition. 
> Also it doesn't scale to more than 2 levels because it stops at the first 
> cause found. I can obviously work around this, but I'm thinking I'm doing 
> this wrong, a defining feature of go is the error handling - surely there's 
> a better way to do it than this!.
>
> Am I doing something unusual here and wanting to determine where in the 
> hierarchy of the stack a problem might have come from? How else do people 
> handle errors in situations like this, where you can't fully handle them 
> locally, so you want to return the error, but then when you get to the 
> higher levels you can handle them, as long as you have information about 
> the error. The annoying thing is, everything is there in the string of the 
> error message and I could strings.Contains my way through the error string 
> to work this out, but that feels a really stupid way to do this.
> I also come across this in my test cases, I want to inject error to make 
> sure I am spotting errors correctly and checking that I am getting the 
> correct error from the correct place is really quite clunky at the moment, 
> if I could test that an error checker in location X was triggered by it 
> being passed an error that would save me a lot of code.
>
> Any suggestions gratefully received.
>
> Regards
>
> Chris
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to