Proper error handling?

251 views
Skip to first unread message

Janne Snabb

unread,
Oct 14, 2012, 11:34:45 PM10/14/12
to golan...@googlegroups.com
Hi,

I have been learning the Go language the past couple of days. I am
struggling to figure out how to properly handle several standard library
error conditions and where to find a list of the possible error
conditions that each function can return.

On Unix/Linux/BSD the syscall and libc manual pages always list all the
possible error conditions for each function. The Go documentation
completely lacks this information unless I am missing something.

Right now I am implementing some code where I do DNS lookups and need to
detect "host not found" error condition and handle it specially. How do
I do this? I would like to do something like the following example:

addrs, err := net.LookupHost(hostname)

if err == net.ErrHostNotFound {
// host was not found, do something
...
} else if err != nil {
// handle other errors
fmt.Writeln("Error:", err)
return
}

Another error that I need to catch is a disk full situation (ENOSPC in
traditional Unix errno terms) when writing to a file with fmt.Fprint().
What should I be looking for in this case? "godoc io" documents a few
I/O error conditions (such as io.EOF) but the list seems to be very
limited.

I hope I am missing something obvious... I would appreciate if someone
could point me to the right direction.

--
Janne Snabb / EPIPE Communications
sn...@epipe.com - http://epipe.com/

Dan Schmidt

unread,
Oct 16, 2012, 12:22:38 AM10/16/12
to golan...@googlegroups.com
As to you first question, I think this may shed some light on what you're trying to achieve:

For instance, our hypothetical callers might want to recover the invalid argument passed to Sqrt. We can enable that by defining a new error implementation instead of using errors.errorString:
type NegativeSqrtError float64
func (f NegativeSqrtError) Error() string {
    return fmt.Sprintf("math: square root of negative number %g", float64(f))
}
A sophisticated caller can then use a type assertion to check for a NegativeSqrtError and handle it specially, while callers that just pass the error to fmt.Println or log.Fatal will see no change in behavior.
As another example, the json package specifies a SyntaxError type that the json.Decode function returns when it encounters a syntax error parsing a JSON blob.
type SyntaxError struct {
    msg    string // description of error
    Offset int64  // error occurred after reading Offset bytes
}
 

func (e *SyntaxError) Error() string { return e.msg }
 
The Offset field isn't even shown in the default formatting of the error, but callers can use it to add file and line information to their error messages:
    if err := dec.Decode(&val); err != nil {
        if serr, ok := err.(*json.SyntaxError); ok {
            line, col := findLine(f, serr.Offset)
            return fmt.Errorf("%s:%d:%d: %v", f.Name(), line, col, err)
        }
        return err
    }

Janne Snabb

unread,
Oct 16, 2012, 12:26:59 PM10/16/12
to golan...@googlegroups.com
On 2012-10-16 11:22, Dan Schmidt wrote:
> As to you first question, I think this may shed some light on what
> you're trying to achieve:
> *Source*: http://golang.org/doc/articles/error_handling.html
[..]
> On Sunday, October 14, 2012 10:50:44 PM UTC-5, Janne Snabb wrote:
[..]
>> Right now I am implementing some code where I do DNS lookups and need to
>> detect "host not found" error condition and handle it specially. How do
>> I do this?
[..]

Hi,

Thanks for the pointer! I have now realized that the error returned by
net.LookupHost() is actually of type struct DNSError which is defined in
net/dnsclient.go. I can use a type assertion to dig into the contents of
that structure:

addrs, err := net.LookupHost(hostname)

if err != nil && err.(*net.DNSError).Err == "no such host" {
// do something appropriate
}

Unfortunately the "no such host" string is not exported from
net/dnsclient.go:

const noSuchHost = "no such host"

Therefore I can not compare the returned error against the noSuchHost
const. I can only hope that nobody ever changes that string in future
version of Go. I think this is not an optimal way of handling errors,
but it is better than needing to do something really ugly like the
following:

if (strings.Contains(err.Error(), "no such host")) {


This looks like something that should be improved in a future version of
Go...

Janne Snabb

unread,
Oct 25, 2012, 9:03:24 AM10/25/12
to golan...@googlegroups.com
On 2012-10-15 10:34, Janne Snabb wrote:

> Right now I am implementing some code where I do DNS lookups and need to
> detect "host not found" error condition and handle it specially. How do
> I do this?

I am replying to myself to update this thread just for the benefit of
others who might need to do DNS lookups in Go and find this thread later
on with a search engine or something.

I found a great Go DNS library at: https://github.com/miekg/dns

It returns proper error codes in addition to implementing everything DNS
related anyone might ever need.

There is another one at https://github.com/cznic/dns but I have not
tried it out yet (it looks more complicated).

The DNS functions in the default "net" package are suitable for only
*very* *basic* things when you absolutely do not care about proper error
handling. Do not use it for anything serious, you will regret.

Miek Gieben

unread,
Oct 25, 2012, 9:07:04 AM10/25/12
to golan...@googlegroups.com
[ Quoting <sn...@epipe.com> in "Re: [go-nuts] Proper error handling..." ]
> On 2012-10-15 10:34, Janne Snabb wrote:
>
> > Right now I am implementing some code where I do DNS lookups and need to
> > detect "host not found" error condition and handle it specially. How do
> > I do this?
>
> I am replying to myself to update this thread just for the benefit of
> others who might need to do DNS lookups in Go and find this thread later
> on with a search engine or something.
>
> I found a great Go DNS library at: https://github.com/miekg/dns
>
> It returns proper error codes in addition to implementing everything DNS
> related anyone might ever need.

thank you :-)

grtz Miek
signature.asc
Reply all
Reply to author
Forward
0 new messages