I’ve worked with Go for a while now and has yet to really nail how I work with errors.
Even the standard library has a number of different ways to deal with errors (some not even making it possible to inspect the errors without having to resort to string matching).
I’ve recently read the blog post Inspecting Errors by Dave Cheney. This sounds like its a step in the right direction, but I’m still having a hard time really putting it to real use.
Say I have made a package a
that does requests to a 3rd party REST API (such as Facebook Graph for instance). I’d like this package to expose functions matching those of the API – lets say GetUser
.
Calling GetUser
can have a number of outcomes:
- Success
- Failed due to request failure like 3rd party API being down
- 3rd party API returned an error (like user not found)
- Deserialization of response or similar failed
Asserting the error for behaviour works very well in the second case. However it falls short in distinguishing between the third and fourth case.
My current use case is implementing my own REST API that use this first package. In this case I’d like be able to return 200 OK
, 503 Service Unavailable
, 400 Bad Request
, 500 Internal Server Error
responses respectively to the possible outcomes.
What would be a good general approach to solving this problem without having to include returning http response codes or similar from package a
?
2
Answers
After working with this for a while without coming any closer to a solution that feels just right I'm coming to terms with there not being a good single solution for this.
I guess this might also be what Dave Cheney means by:
Since I still want to avoid type asserting the error due to the dependency challenges that brings I've ended up introducing an
Internal() bool
behaviour similar to theTemporary() bool
pattern mentioned in the linked articles.This at least allow me to assert the behavior without being forced to import the package that originally created the error.
It's not the best fit, but it will have to do for now.
Ainar-G's answer is worth taking a look at as well.
What I’d do is define a few “wrapper errors” to signify where error has actually happened. E.g.
And then in the code of your API Client:
Then, you can do this: