From 15b2834d5e9619431f197561e30cfea3802f7474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A0=20Gregory=20L=2E=20Dietsche=20=E2=9C=A0?= Date: Mon, 26 Aug 2024 07:14:40 -0500 Subject: [PATCH] fix proxy retry loop This addresses two bugs: 1) The loop could exit with an error condition present and fail to inform the user. 2) On Windows 11, syscall.ECONNREFUSED is not returned. Instead we receive net.OpError with a message similar to: "unable to reach app: Get "http://localhost:7000/": dial tcp [::1]:7000: connectex: No connection could be made because the target machine actively refused it." The Fix: Since the retry loop is short; just 1 second maximum, we retry until no error happens. If an error does occur, we inform the user. --- runner/proxy.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/runner/proxy.go b/runner/proxy.go index 6e3bad76..70614475 100644 --- a/runner/proxy.go +++ b/runner/proxy.go @@ -2,14 +2,12 @@ package runner import ( "bytes" - "errors" "fmt" "io" "log" "net/http" "strconv" "strings" - "syscall" "time" ) @@ -106,18 +104,20 @@ func (p *Proxy) proxyHandler(w http.ResponseWriter, r *http.Request) { } req.Header.Set("X-Forwarded-For", r.RemoteAddr) - // retry on connection refused error since after a file change air will restart the server and it may take a few milliseconds for the server to be up-and-running. + // air will restart the server. it may take a few milliseconds for it to start back up. + // therefore, we retry until the server becomes available or this retry loop exits with an error. var resp *http.Response + resp, err = p.client.Do(req) for i := 0; i < 10; i++ { - resp, err = p.client.Do(req) if err == nil { break } - if !errors.Is(err, syscall.ECONNREFUSED) { - http.Error(w, "proxy handler: unable to reach app", http.StatusInternalServerError) - return - } time.Sleep(100 * time.Millisecond) + resp, err = p.client.Do(req) + } + if err != nil { + http.Error(w, "proxy handler: unable to reach app", http.StatusInternalServerError) + return } defer resp.Body.Close()