Error, not concrete type

I read the section from the Go FAQ about error handling and I have a question about it. This section states that it is a good practice for functions that return an error to always return error, and not concrete error.

As an example, os.Open is given, which returns error, although in fact it is always *os.PathError . This approach is insisted because of the fact that it helps to ensure that error is created correctly. “Correctly” means not getting into a trap of a gotcha, related to the fact that error is an interface and therefore that line return p , where p is *MyError will actually always return a non-nil error interface.

I don’t understand why this kind of code is considered bad. It seems strange to me that function os.Open returns error by signature, but in fact it is always returns *os.PathError , which is stated for some reason in the docs, but not in the function signature.

I do not understand the motivation for this approach. Could someone please explain to me why it is done this way?

1 Like

Assuming your question is about why a function signature should specify an error interface as its return type instead of a concrete type, my answer is: for the same reasons that you would want to use interfaces in any other situation including reduced API coupling (any code that knows how to handle an error would know how to handle your returned error) and hiding your internal data structures (so you could change the internal representation of your error without affecting programs that depend on your code).

Also see https://go101.org/article/interface.html and https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully

2 Likes