You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Golang中如何更可靠地检测HTTP代理相关错误?

如何可靠检测WebSocket代理相关错误?

我有一个通过代理服务器连接服务端的小型WebSocket客户端,相关代码如下:

proxyURL, err := url.Parse("http://10.207.80.10:8081")
if err != nil {
    log.Fatal("Failed to parse proxy URL:", err)
}

httpTransport := &http.Transport{
    Proxy: http.ProxyURL(proxyURL),
}

httpClient := &http.Client{
    Transport: httpTransport,
}

opts := &websocket.DialOptions{
    HTTPClient: httpClient,
}

ctx := context.Background()
conn, _, err := websocket.Dial(ctx, "ws://localhost:8080/ws", opts)
if err != nil {
    log.Fatal("Failed to connect to WebSocket server: ", err)
}

现在需要检测各类由代理引发的错误,例如:

  • 代理未运行时,会出现“no route to host”错误
  • 代理URL错误时,会出现“connection refused”错误
  • 代理凭据错误时,会出现“Proxy Authentication Required”错误

原本考虑使用字符串匹配的方式检测:

if strings.Contains(err.Error(), "proxyconnect tcp") {
        log.Println("Proxy connection error:", err)
        return
    }

但这种方法无法覆盖代理认证错误等情况,请问是否有更可靠的方法来检测各类代理相关错误(如代理URL配置错误、认证错误、代理未运行等)?


更可靠的错误检测方案

不要依赖字符串匹配,而是通过类型断言和HTTP状态码检查精准识别代理相关错误,分三类场景处理:

1. 代理URL配置错误(提前拦截)

这部分已经在url.Parse阶段处理,直接捕获解析错误即可,属于初始化阶段的配置问题,无需后续额外处理。

2. 代理网络连接错误(如代理未运行、地址错误)

这类错误属于网络层面的操作错误,Go标准库会返回*net.OpError类型,其中Op字段会标记为proxyconnect,通过类型断言精准匹配:

var opErr *net.OpError
if errors.As(err, &opErr) {
    if opErr.Op == "proxyconnect" {
        log.Println("代理网络连接错误:", err)
        // 可进一步区分具体错误类型,比如通过opErr.Err的内容判断是"no route to host"还是"connection refused"
        return
    }
}

3. 代理认证错误(407状态码)

当代理要求认证但未提供有效凭据时,会返回HTTP 407状态码。WebSocket握手失败时,websocket.Dial会返回对应的*http.Response,直接检查状态码即可:

// 保留Dial的第二个返回值resp
conn, resp, err := websocket.Dial(ctx, "ws://localhost:8080/ws", opts)
if err != nil {
    if resp != nil && resp.StatusCode == http.StatusProxyAuthRequired {
        log.Println("代理认证错误:需要提供有效凭据")
        return
    }
    // 其他错误处理...
}

完整错误处理示例

整合所有场景后的代码:

proxyURL, err := url.Parse("http://10.207.80.10:8081")
if err != nil {
    log.Fatal("代理URL解析错误:", err)
}

httpTransport := &http.Transport{
    Proxy: http.ProxyURL(proxyURL),
}

httpClient := &http.Client{
    Transport: httpTransport,
}

opts := &websocket.DialOptions{
    HTTPClient: httpClient,
}

ctx := context.Background()
conn, resp, err := websocket.Dial(ctx, "ws://localhost:8080/ws", opts)
if err != nil {
    // 检测代理认证错误
    if resp != nil && resp.StatusCode == http.StatusProxyAuthRequired {
        log.Println("代理认证失败:Proxy Authentication Required")
        return
    }

    // 检测代理网络连接错误
    var opErr *net.OpError
    if errors.As(err, &opErr) {
        if opErr.Op == "proxyconnect" {
            log.Println("代理网络连接异常:", err)
            return
        }
    }

    // 其他WebSocket连接错误
    log.Fatal("WebSocket连接失败:", err)
}

// 连接成功后的逻辑...

这种方式不依赖错误信息的字符串内容,完全基于Go的错误类型和HTTP标准状态码,兼容性和可靠性更强,能覆盖所有你提到的代理错误场景。

内容的提问来源于stack exchange,提问作者ray an

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:45:23