Go: proposal: error classification

Created on 8 Apr 2016  Â·  17Comments  Â·  Source: golang/go

Problem

Go currently has error classification scattered throughout the standard library (and elsewhere).

Programmers usually just need an answer to these questions:

  • Does it help, if I retry (e.g. via exponential backoff)? After how much time?
  • Should I increase this timeout? By how much?
  • Should I create instead of update?
  • Did I lookup/get by the wrong key?
  • Do I need more permissions or some auth to access this item?
  • Should I throttle my rate of actions? (e.g. file system access, api access) What rate would be ok?
  • Is this error a final error and I should better stop the program to avoid further damage?
  • Is an unknown error? (imagine as default case in a switch)
  • Is an error unexpected in this context? (e.g. io.UnexpectedEOF is such an error class or errors.New("unimplemented") while building software iteratively)
  • What should I report as an underlying cause?
  • Should I augment the error or just pass on?
  • ... anything I didn't consider yet...

Proposed Solution

Define interfaces to answer most of these questions in a way that allows programs to answer these questions in a uniform way and allows packages to communicate these situations in a uniform way,
but without restricting level of detail.

The details can be fleshed out once the need of a solution is ackknowledged.

Alternate Solutions

  • Error registry which every programmer should know
  • importing unneeded dependencies in high level abstract code, just because it could be that we see this kind of error and want to handle it in a sane way.
  • putting adapters around those errors as in http://alistair.cockburn.us/Hexagonal+architecture
  • anything I don't see at the moment
FrozenDueToAge Go2 Proposal error-handling

Most helpful comment

No jokes. I think you will live to see Go 2.

All 17 comments

Anyone have any opinions on this?

I'm not sure what the concrete proposal is.

I suspect introducing new interfaces might be problematic if existing errors can't satisfy them for Go 1 compat reasons. I think more helpers like os.IsNotExist might be more tenable.

  • Do I need more permissions or some auth to access this item?

Are you proposing for example an IsPermissionError() bool interface somewhere, and then making https://golang.org/pkg/os/#IsPermission respect it?

Do you have a full list of your proposed additions?

Are you proposing for example an IsPermissionError() bool interface somewhere, and then making https://golang.org/pkg/os/#IsPermission respect it?

Yes, that is exatctly what I mean.

I also want to work out where to put such helpers and how to make them more easily discoverable.

Do you have a full list of your proposed additions?

The full list I have at the moment is the bulleted list below "Programmers usually just need an answer to these questions:" in the issue I am commenting here. We just need to convert the prose there into function names. I would like to bikeshed on those function names later, ok?

What I need to know now is:

  • Do you guys feel the pain too?
  • Do you agree to the basic idea of the cure?
  • Do you suggest a wildly different road here? Which one?

Ping?

Sorry, we've gotten behind on proposals. In the past week or so we've started to making progress on going through them, though.

I think this proposal needs something a bit more concrete. Do you have a prototype we can look at to see its implications on the standard library? (we can quibble over naming later, but you can pick stuff for now)

@davecheney probably has thoughts on this proposal too.

I don't understand what you are proposing, sorry.

Ok, will code up a prototype package for this in the next few days. Thanks for telling me how to proceed here, since that unblocked this issue for me now.

One major issue with standardized classification is that it is incredibly difficult coming up with a set of "classes" that everybody agrees upon. Even worse, the various classifications often have some overlap with each other such that it is difficult at times figuring out exactly which classification a given error falls under.

The first question to answer is, what are the "common" classes that should be defined? Follow up questions are: is this set fixed or do we allow people to extend them?

One attempt at such classification (and arising from some of the problems faced at Google) are the codes found in GRPC. I'm not saying that this is a good set of classifications, but it is one attempt.

Supposing that you could agree upon a set of common classes, the next question is how do we get errors to be classified as a given type? Possible solutions:

  • For every class, require that they satisfy an IsX interface (as you proposed) such that the satisfaction of that interface indicates that it is of that class. If so, what does it mean if an error satisfies multiple classifications?
  • Suppose that the classifications are essentially globally agreed upon (which is hard) and mapped to an enum, you could require that errors satisfy a ErrorCode interface that allows you to query for the error code (similar to GRPC).

Personally, I recognize that there is a problem. However, I'm not convinced that a common set of standardized classification is feasible, but I'm willing to see discussion about this. Unless the standardized set is _concisely_ suitable for majority of use cases, I believe that having a pre-defined set is more harm than good.

@bradfitz / @davecheney rough prototype here: https://godoc.org/github.com/nightlyone/errorclass

It has no dependencies (and the hacky generator at gen-types.go is just for me now, please ignore it).

@dsnet Thanks for pointing me to the gRPC error classification codes. I incorporated their code names and parts of their description in the proposal. Multiple classifications are ok and also intended. In some cases they make no sense, but that can be enforced by the provided IsFoo-functions. Distinct error taxonomy is much harder than just suggesting error handling strategies.

To define what common errors exist, just ask yourself and your buddies which kinds of errors they built error handling for in their programs in the last few years.

And since all errors are nothing else but distinct interfaces, the list is completely extensible forever without without ever breaking any users.

Thank you for explaining. My inital reaction is this is not useful enough,
and would begat the inclusion of even more helpers.

On Tue, 23 Aug 2016, 05:52 Ingo Oeser [email protected] wrote:

@bradfitz https://github.com/bradfitz / @davecheney
https://github.com/davecheney rough prototype here:
https://godoc.org/github.com/nightlyone/errorclass

It has no dependencies (and the hacky generator at gen-types.go is just
for me now, please ignore it).

@dsnet https://github.com/dsnet Thanks for pointing me to the gRPC
error classification codes
https://godoc.org/google.golang.org/grpc/codes. I incorporated their
code names and parts of their description in the proposal. Multiple
classifications are ok and also intended. In some cases they make no sense,
but that can be enforced by the provided IsFoo-functions. Distinct error
taxonomy is much harder than just suggesting error handling strategies.

To define what common errors exist, just ask yourself and your buddies
which kinds of errors they built error handling for in their programs in
the last few years.

And since all errors are nothing else but distinct interfaces, the list is
completely extensible forever without without ever breaking any users.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/golang/go/issues/15192#issuecomment-241529163, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAcA60AkYNH_HiMYtNPcFKwMG7u_UFbks5qif3qgaJpZM4IC9aq
.

I think it's a bit late in the game for this. Maybe there is some canonical taxonomy of error types that we could think about for Go 2. What you have proposed in your prototype seems arbitrary to me, though. My gut instinct is that we would have a small set (3-4?) of very broad error types.

I have neither the time nor the interest following this through until Go2 (which is basically never happening till I die, I guess), so I gonna close it.

Please re-open, if there is serious interest in the Go team. This seems like a joke to me...

No jokes. I think you will live to see Go 2.

@adg With all due respect, why do you think this issue should be held off till Go2? If we can improve Go without making breaking changes, why delay? There's no timeline for Go2, right?

Yes, if we can improve Go without making breaking changes, we should. But every change is a tradeoff. It's not obvious that this specific proposal is a sufficiently useful non-breaking improvement.

@ianlancetaylor Makes sense. I came here via https://github.com/golang/go/issues/18303. It seems clear that most everyone, including the Go team, recognizes that the lack of context from standard library errors is an issue, but the "correct solution" is unknown.

Is there an open issue for addressing this, alike https://github.com/golang/go/issues/15292? I think Cause() error is a good start, but I'm curious what other solutions are being considered.

@tejasmanohar Good question. I don't know of one.

Was this page helpful?
0 / 5 - 0 ratings