英文:
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")
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论