How to specify and handle specific errors in Go?

huangapple go评论72阅读模式
英文:

How to specify and handle specific errors in Go?

问题

我写了一个非常基本的解析器,用于处理 Reddit 的 JSON 数据,我想知道如何在 Go 中特定地处理错误。

例如,我有一个用于获取链接的 "Get" 方法:

func Get(reddit string) ([]Item, error) {
    url := fmt.Sprintf("http://reddit.com/r/%s.json", reddit)
    resp, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK {
        return nil, err
    }
    /*
     * 其他代码在这里
     */
}

我该如何处理 StatusCode 的 404 错误?我知道我可以测试是否为 404 错误本身:

if resp.StatusCode == http.StatusNotFound {
    // 在这里执行操作
}

但是有没有一种方法可以直接处理 resp.StatusCode != http.StatusOK,而不必编写一堆 if 语句?我能否在 switch 语句中使用 err

英文:

I wrote this very basic parser that goes through Reddit JSON and am curious how I can specifically manage an error in Go.

For example I have this "Get" method for a link:

func Get(reddit string) ([]Item, error) {
	url := fmt.Sprintf("http://reddit.com/r/%s.json", reddit)
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return nil, err
	}
	/*
     * Other code here
    */
}

How can I handle, say, a 404 error from the StatusCode? I know I can test for the 404 error itself:

if resp.StatusCode == http.StatusNotfound {
    //do stuff here
}

But is there a way I can directly manage the resp.StatusCode != http.StatusOK without having to write a bunch of if statements? Is there a way I can use err in a switch statement?

答案1

得分: 1

首先请注意,http.Get 在遇到 HTTP 返回码不是 200 的情况下并不会返回错误。即使服务器返回了 404 错误,Get 方法仍然成功完成了它的工作。根据文档的说明:

> 非 2xx 响应不会引发错误。

因此,在你的代码中,当你调用这个方法时,err 将会是 nil,这意味着它会返回 err=nil,这可能不是你想要的结果。

if resp.StatusCode != http.StatusOK {
    return nil, err
}

下面的代码可以实现你想要的效果:

if resp.StatusCode != http.StatusOK {
    return nil, fmt.Errorf("HTTP Error %d: %s", resp.StatusCode, resp.Status)
}

这样就会针对任何类型的 HTTP 错误返回一个带有错误信息的错误。

英文:

Firstly note that http.Get doesn't return an error for an HTTP return which isn't 200. The Get did its job successfully even when the server gave it a 404 error. From the docs

> A non-2xx response doesn't cause an error.

Therfore in your code, err will be nil when you call this which means it will return err=nil which probably isn't what you want.

if resp.StatusCode != http.StatusOK {
    return nil, err
}

This should do what you want

if resp.StatusCode != http.StatusOK {
    return nil, fmt.Errorf("HTTP Error %d: %s", resp.StatusCode, resp.Status)
}

Which will return an error for any kind of HTTP error, with a message as to what it was.

答案2

得分: 0

当然可以:

package main

import "fmt"

func main() {
    var err error
    switch err {
    case nil:
        fmt.Println("是 nil")
    }
}

链接:https://play.golang.org/p/4VdHW87wCr

英文:

Sure you can:

package main

import "fmt"

func main() {
	var err error
	switch err {
	case nil:
		fmt.Println("Is nil")
	}
}

https://play.golang.org/p/4VdHW87wCr

huangapple
  • 本文由 发表于 2015年1月4日 04:05:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/27759024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定