Golang HTTP请求错误恐慌恢复



我是Golang编码的新手,并且正在为不良URL请求而陷入恐慌/恢复过程。下面是一个脚本,查询URL列表并输出响应列表。有时会输入不良的URL或服务器下降,而HTTP请求失败,这会引起恐慌。我不清楚如何从中恢复并继续。我希望该程序从恐慌中恢复,记录错误的URL和错误,并继续使用其余的正常URL响应数据输出失败URL和错误的URL列表。

package main
import (
    "fmt"
    "net/http"
)
var urls = []string{
    "http://www.google.com",        //good url, 200
    "http://www.googlegoogle.com/", //bad url
    "http://www.zoogle.com",        //500 example
}
//CONCURRENT HTTP REQUESTS -------------------------------------------
func MakeRequest(url string, ch chan<- string) {
    resp, err := http.Get(url)
    if err != nil {
        fmt.Println("Error Triggered", err)
        ch <- fmt.Sprintf("err: %s", err)
    }
    ch <- fmt.Sprintf("url: %s, status: %s ", url, resp.Status) // put response into a channel
    resp.Body.Close()
}
func main() {
    output := make([][]string, 0) //define an array to hold responses
    //PANIC RECOVER------------------------------
    defer func() { //catch or finally
        if r := recover(); r != nil { //catch
            fmt.Println("Recover Triggered: ", r)
        }
    }()
    //MAKE URL REQUESTS----------------------------------------------
    for _, url := range urls {
        ch := make(chan string)                 //create a channel for each request
        go MakeRequest(url, ch)                 //make concurrent http request
        output = append(output, []string{<-ch}) //append output to an array
    }
    //PRINT OUTPUT ----------------------
    for _, value := range output {
        fmt.Println(value)
    }
}

我正在寻找类似的输出:

[url:http://www.google.com,状态:200 ok]

[url:http://www.googlegoogle.com,err:没有这样的主机]

[url:http://www.zoogle.com,状态:500内部服务器错误]

谢谢吉姆·B。我以为恐慌是由请求触发的,但由于不存在,这是尝试将" resp.status"用于失败的请求。如果没有错误,我修改了错误处理以仅在" CH"中放置一个resp.Status。在错误的情况下,我将不同的响应用在" CH"中代替误差值。由于没有触发恐慌,因此无需恢复。

func MakeRequest(url string, ch chan<- string) {
    resp, err := http.Get(url)
    if err != nil {
        ch <- fmt.Sprintf("url: %s, err: %s ", url, err)
    } else {
        ch <- fmt.Sprintf("url: %s, status: %s ", url, resp.Status) // put response into a channel
        defer resp.Body.Close()
    }
}

输出现在是:

[url:http://www.google.com,状态:200 ok]

[url:http://www.googlegoogle.com/,err:获取http://www.googlegoogle.com/:dial tcp:lookup www.googlegoogle.com:没有这样的主机

[url:http://www.zoogle.com,状态:500内部服务器错误]

我唯一(并做)恢复的地方:在"故障障碍"中。

"故障屏障"是最高的中心问题的地方。通常,这是一个新的Goroutine产生的地方(即:Per http Accept)。在ServeHTTP方法中,您可能需要在不重新启动服务器的情况下捕获和记录单个恐慌(通常是这种恐慌是微不足道的nil ptr derefs)。您可能会在无法检查需要知道的条件的地方看到恢复 - 例如文件手是否已经关闭。(只需关闭并处理可能的恐慌)。

我有一个仅使用2或3次的大型代码库。它们仅适用于提到的案例,我只能确保该问题是专门记录的。即使我仍然要去OS.EXIT并让启动我重新启动我的脚本,我也会进行恢复。

最新更新