internal/worker: proxy timeouts should be retryable

When fetching e.g. the master branch, it is common for the proxy client
to timeout as it waits for the branch to be resolved.

This should be a retryable error, as otherwise we end up in a state
where an asynchronous refresh of master actually breaks documentation at
master.

There is still a problem that documentation is broken after the first
failure, but this at least puts us in a recoverable state.

Again, as with CL 482162 this is unfortunately not possible to test in
the current setup without significant refactoring. Such refactoring may
be warranted, but I do not have time to do this now.

Updates golang/go#59464

Change-Id: I321cc2eaabac1d7e052d07efcaadefcac24208ac
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/484736
Reviewed-by: Jamal Carvalho <jamal@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
diff --git a/internal/worker/server.go b/internal/worker/server.go
index e6af6ce..0bef928 100644
--- a/internal/worker/server.go
+++ b/internal/worker/server.go
@@ -305,6 +305,16 @@
 		http.Error(w, http.StatusText(code), code)
 		return
 	}
+
+	// Proxy timeouts are retryable, since they occur when e.g. a branch pointer
+	// such as master needs to be re-fetched.
+	if code == derrors.ToStatus(derrors.ProxyTimedOut) {
+		log.Infof(r.Context(), "doFetch of %s returned %d (proxy timeout); returning 500 retry task", r.URL.Path, code)
+		code := http.StatusInternalServerError
+		http.Error(w, http.StatusText(code), code)
+		return
+	}
+
 	if code/100 != 2 {
 		log.Infof(r.Context(), "doFetch of %s returned code %d; returning OK to avoid retry", r.URL.Path, code)
 	}