diff --git a/enterprise/coderd/proxyhealth/proxyhealth.go b/enterprise/coderd/proxyhealth/proxyhealth.go index 4b9e3f13982f8..9f3abdac849f2 100644 --- a/enterprise/coderd/proxyhealth/proxyhealth.go +++ b/enterprise/coderd/proxyhealth/proxyhealth.go @@ -289,7 +289,27 @@ func (p *ProxyHealth) runOnce(ctx context.Context, now time.Time) (map[uuid.UUID case err == nil && resp.StatusCode != http.StatusOK: // Unhealthy as we did reach the proxy but it got an unexpected response. status.Status = Unhealthy - status.Report.Errors = []string{fmt.Sprintf("unexpected status code %d", resp.StatusCode)} + var builder strings.Builder + // This string is shown on the UI where newlines are respected. + // This error message is not ever decoded programmatically, so keep it human- + // readable. + builder.WriteString(fmt.Sprintf("unexpected status code %d. ", resp.StatusCode)) + builder.WriteString(fmt.Sprintf("\nEncountered error, send a request to %q from the Coderd environment to debug this issue.", reqURL)) + err := codersdk.ReadBodyAsError(resp) + if err != nil { + var apiErr *codersdk.Error + if xerrors.As(err, &apiErr) { + builder.WriteString(fmt.Sprintf("\nError Message: %s\nError Detail: %s", apiErr.Message, apiErr.Detail)) + for _, v := range apiErr.Validations { + // Pretty sure this is not possible from the called endpoint, but just in case. + builder.WriteString(fmt.Sprintf("\n\tValidation: %s=%s", v.Field, v.Detail)) + } + } else { + builder.WriteString(fmt.Sprintf("\nError: %s", err.Error())) + } + } + + status.Report.Errors = []string{builder.String()} case err != nil: // Request failed, mark the proxy as unreachable. status.Status = Unreachable