2

I have a server that I am writing, and I want to handle errors from conn.Read(). Specifically, I want to do nothing in the case that the client has closed the connection, but log the error if it is any other error. I have encountered the following problems:

  1. The documentation does not seem to say what the errors that conn.Read() can return.
  2. Connection-closed-by-client seems to be an EOF error. Turns out that it's type is error.errorString. Seriously?

So basically I have to do a string comparison to "EOF" to tell if my error is expected or a genuine error?!? Am I missing something? Because this seems like a huge oversight at the moment...

1 Answer 1

2

Well, no, it's string because it's defined as

import "errors"
...
var EOF = errors.New("EOF")

and what errors.New(string) returns is really a type convertible to string because that type, errorString merely embeds a string you're passing to error.New(string) with the sole purpose of defining the Error() string method on it—to satisfy the error interface.

But you test for this specific error (end of file) like this:

import "io"
...
if err == io.EOF {
...

That is, you're not comparing strings but rather addresses of a well-known variable exported by a certain library module ("io" in this case).

5
  • Ah, excellent! So how would I discover that the error I want to check for is io.EOF without asking StackOverflow? I assume there's something in the documentation that I missed?
    – prewett
    Commented Jul 23, 2014 at 8:26
  • To clarify, I assume that there was something in the documentation that I missed somewhere that would point me to look at the io package, even though I wasn't using any functions from io?
    – prewett
    Commented Jul 23, 2014 at 8:36
  • @prewett, well, I'm afraid that there's indeed no obvious connection, or, rather it is obvious to folks with certain mindset--let me explain. Go is very orthogonal and minimal, so really all the types in its stdlib which read bytes satisfy the io.Reader interface, and once you got to know this the idea the Read() method on a type implementing a TCP stream of bytes returns what io.Reader.Read() is defined to return upon encountering EOF is kind of self-evident.
    – kostix
    Commented Jul 23, 2014 at 21:01
  • @prewett, the question of how to get there is more complicated... I assume most folks at some point read most of blog.golang.org articles (must read, really), the "Effective Go" document and other stuff like this go-to explanation of interfaces in Go, and then they have all the necessary parts of this "puzzle" in their brains.
    – kostix
    Commented Jul 23, 2014 at 21:05
  • I had a feeling that's what the answer would be... "Effective Go" is obviously necessary, but it has no answer to this question. I'm really disappointed in the poor documentation Go has, really among the worst I've used. And then, I discovered that if you want to find out if the error is a timeout, you appear to need to do "if netErr, ok := err.(net.Error); ok && netErr.Timeout()" which is completely inconsistent. Thanks for the other links, I'll read through them.
    – prewett
    Commented Jul 24, 2014 at 8:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.