Search code examples
goproxy

Check for http proxy errors in Golang


I have a small WebSocket client that connects to a server via a proxy server.

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)
    }

Now, I need to detect the errors that we could because of proxy.

e.g. When no proxy is running, I got this

Failed to connect to WebSocket server: failed to WebSocket dial: failed to send handshake request: Get "http://localhost:8080/ws": proxyconnect tcp: dial tcp 10.207.80.10:8081: connect: no route to host

When I used incorrect ProxyURL (and proxy was running), I got this

Failed to connect to WebSocket server: failed to WebSocket dial: failed to send handshake request: Get "http://localhost:8080/ws": proxyconnect tcp: dial tcp 10.207.80.10:8081: connect: connection refused

I got Proxy Authorization error when I use incorrect creds

Failed to connect to WebSocket server: failed to WebSocket dial: failed to send handshake request: Get "http://localhost:8080/ws": Proxy Authentication Required

I was thinking about using below:

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

but it doesn't handle Proxy Auth (and maybe some other errors that could be because of proxy).

Is there any other more robust way to check for different proxy errors? (e.g. configuration errors like incorrect proxy URL, Auth Errors or proxy is not running)

Thanks!


Solution

  • You can access the underlying cause using the errors.Unwrap function

    conn, _, err := websocket.Dial(ctx, "ws://localhost:8080/ws", opts)
    if err != nil {
        cause := errors.Unwrap(err)
        if cause != nil {
            err = cause
        }
    }