Skip to content

Commit c07bebb

Browse files
LucasRoesleralexellis
authored andcommitted
fix: return provider response during fnc listing errors
Return the original upstream response body when the the list request returns an error. In general, the provider is returning useful and actionable error messages for the user, the previous code hid this in the logs and this is easy for user to overlook. Additionally, remove an early return from error case after fetching metrics. This looked like a bug and could result in empty api responses if there was a prometheus error. Signed-off-by: Lucas Roesler <[email protected]>
1 parent 208b1b2 commit c07bebb

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

gateway/metrics/add_metrics.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,13 @@ func AddMetricsHandler(handler http.HandlerFunc, prometheusQuery PrometheusQuery
3434
log.Printf("List functions responded with code %d, body: %s",
3535
recorder.Code,
3636
string(upstreamBody))
37-
38-
http.Error(w, "Metrics handler: unexpected status code from provider listing functions", http.StatusInternalServerError)
37+
http.Error(w, string(upstreamBody), recorder.Code)
3938
return
4039
}
4140

4241
var functions []types.FunctionStatus
4342

4443
err := json.Unmarshal(upstreamBody, &functions)
45-
4644
if err != nil {
4745
log.Printf("Metrics upstream error: %s, value: %s", err, string(upstreamBody))
4846

@@ -63,8 +61,8 @@ func AddMetricsHandler(handler http.HandlerFunc, prometheusQuery PrometheusQuery
6361

6462
results, err := prometheusQuery.Fetch(url.QueryEscape(q))
6563
if err != nil {
64+
// log the error but continue, the mixIn will correctly handle the empty results.
6665
log.Printf("Error querying Prometheus: %s\n", err.Error())
67-
return
6866
}
6967
mixIn(&functions, results)
7068
}

gateway/metrics/add_metrics_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"log"
66
"net/http"
77
"net/http/httptest"
8+
"strings"
89
"testing"
910

1011
types "github.com/openfaas/faas-provider/types"
@@ -55,6 +56,34 @@ func Test_PrometheusMetrics_MixedInto_Services(t *testing.T) {
5556
}
5657
}
5758

59+
func Test_MetricHandler_ForwardsErrors(t *testing.T) {
60+
functionsHandler := func(w http.ResponseWriter, r *http.Request) {
61+
w.WriteHeader(http.StatusConflict)
62+
w.Write([]byte("test error case"))
63+
}
64+
// explicitly set the query fetcher to nil because it should
65+
// not be called when a non-200 response is returned from the
66+
// functions handler, if it is called then the test will panic
67+
handler := AddMetricsHandler(functionsHandler, nil)
68+
69+
rr := httptest.NewRecorder()
70+
request, _ := http.NewRequest(http.MethodGet, "/system/functions", nil)
71+
handler.ServeHTTP(rr, request)
72+
73+
if status := rr.Code; status != http.StatusConflict {
74+
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusConflict)
75+
}
76+
77+
if rr.Header().Get("Content-Type") != "text/plain; charset=utf-8" {
78+
t.Errorf("Want 'text/plain; charset=utf-8' content-type, got: %s", rr.Header().Get("Content-Type"))
79+
}
80+
body := strings.TrimSpace(rr.Body.String())
81+
if body != "test error case" {
82+
t.Errorf("Want 'test error case', got: %q", body)
83+
}
84+
85+
}
86+
5887
func Test_FunctionsHandler_ReturnsJSONAndOneFunction(t *testing.T) {
5988
functionsHandler := makeFunctionsHandler()
6089

0 commit comments

Comments
 (0)