diff --git a/internal/index/index.go b/internal/index/index.go
index 33a408c..e3c7de8 100644
--- a/internal/index/index.go
+++ b/internal/index/index.go
@@ -9,6 +9,7 @@
"context"
"encoding/json"
"fmt"
+ "io"
"net/http"
"net/url"
"strconv"
@@ -60,6 +61,14 @@
return nil, fmt.Errorf("ctxhttp.Get(ctx, nil, %q): %v", u, err)
}
defer r.Body.Close()
+ if r.StatusCode != http.StatusOK {
+ body, _ := io.ReadAll(io.LimitReader(r.Body, 4<<10))
+ bodyText := strings.TrimSpace(string(body))
+ if bodyText == "" {
+ return nil, fmt.Errorf("module index returned %s", r.Status)
+ }
+ return nil, fmt.Errorf("module index returned %s: %s", r.Status, bodyText)
+ }
var versions []*internal.IndexVersion
dec := json.NewDecoder(r.Body)
diff --git a/internal/index/index_test.go b/internal/index/index_test.go
index ae8d777..23fb6cb 100644
--- a/internal/index/index_test.go
+++ b/internal/index/index_test.go
@@ -6,6 +6,10 @@
import (
"context"
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "strings"
"testing"
"time"
@@ -59,3 +63,52 @@
})
}
}
+
+func TestGetVersionsHTTPStatus(t *testing.T) {
+ for _, test := range []struct {
+ name string
+ statusCode int
+ body string
+ wantErr string
+ }{
+ {
+ name: "500 empty body",
+ statusCode: http.StatusInternalServerError,
+ wantErr: "module index returned 500 Internal Server Error",
+ },
+ {
+ name: "500 text body",
+ statusCode: http.StatusInternalServerError,
+ body: "backend unavailable",
+ wantErr: "module index returned 500 Internal Server Error: backend unavailable",
+ },
+ {
+ name: "500 valid NDJSON body",
+ statusCode: http.StatusInternalServerError,
+ body: `{"Path":"example.com/mod","Version":"v1.0.0"}`,
+ wantErr: "module index returned 500 Internal Server Error",
+ },
+ {
+ name: "429",
+ statusCode: http.StatusTooManyRequests,
+ wantErr: "module index returned 429 Too Many Requests",
+ },
+ } {
+ t.Run(test.name, func(t *testing.T) {
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(test.statusCode)
+ fmt.Fprint(w, test.body)
+ }))
+ defer server.Close()
+
+ client, err := New(server.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, err = client.GetVersions(context.Background(), time.Time{}, 10)
+ if err == nil || !strings.Contains(err.Error(), test.wantErr) {
+ t.Fatalf("client.GetVersions() error = %v, want error containing %q", err, test.wantErr)
+ }
+ })
+ }
+}