fix: add detailed watch-order logs
This commit is contained in:
@@ -50,8 +50,21 @@ func (c *Client) getWatchOrder(ctx context.Context, id int) (watchorder.WatchOrd
|
||||
|
||||
result, err := watchorder.FetchWatchOrder(requestCtx, c.httpClient, watchOrderURL)
|
||||
if err != nil {
|
||||
var statusError *watchorder.HTTPStatusError
|
||||
if errors.Is(err, watchorder.ErrWatchOrderMarkupNotFound) {
|
||||
log.Printf("relations: watch-order markup missing for %d (%s): %v", id, watchOrderURL, err)
|
||||
} else if errors.As(err, &statusError) {
|
||||
log.Printf(
|
||||
"relations: watch-order http error for %d (%s): status=%d server=%q cf_ray=%q location=%q content_type=%q body=%q",
|
||||
id,
|
||||
watchOrderURL,
|
||||
statusError.StatusCode,
|
||||
statusError.Server,
|
||||
statusError.CFRay,
|
||||
statusError.Location,
|
||||
statusError.ContentType,
|
||||
statusError.BodyPreview,
|
||||
)
|
||||
} else {
|
||||
log.Printf("relations: watch-order fetch failed for %d (%s): %v", id, watchOrderURL, err)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -19,6 +20,29 @@ var idPattern = regexp.MustCompile(`/id/(\d+)`)
|
||||
var ErrInvalidWatchOrderURL = errors.New("invalid watch order url")
|
||||
var ErrWatchOrderMarkupNotFound = errors.New("watch order markup not found")
|
||||
|
||||
type HTTPStatusError struct {
|
||||
StatusCode int
|
||||
URL string
|
||||
Server string
|
||||
CFRay string
|
||||
Location string
|
||||
ContentType string
|
||||
BodyPreview string
|
||||
}
|
||||
|
||||
func (e *HTTPStatusError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"unexpected status code: %d (url=%s server=%s cf_ray=%s location=%s content_type=%s body=%q)",
|
||||
e.StatusCode,
|
||||
e.URL,
|
||||
e.Server,
|
||||
e.CFRay,
|
||||
e.Location,
|
||||
e.ContentType,
|
||||
e.BodyPreview,
|
||||
)
|
||||
}
|
||||
|
||||
type WatchOrderEntry struct {
|
||||
ID int `json:"id"`
|
||||
Type string `json:"type"`
|
||||
@@ -76,7 +100,16 @@ func fetchDocument(ctx context.Context, httpClient *http.Client, url string) (*g
|
||||
defer response.Body.Close()
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("unexpected status code: %d", response.StatusCode)
|
||||
body, _ := io.ReadAll(io.LimitReader(response.Body, 512))
|
||||
return nil, &HTTPStatusError{
|
||||
StatusCode: response.StatusCode,
|
||||
URL: url,
|
||||
Server: strings.TrimSpace(response.Header.Get("Server")),
|
||||
CFRay: strings.TrimSpace(response.Header.Get("CF-Ray")),
|
||||
Location: strings.TrimSpace(response.Header.Get("Location")),
|
||||
ContentType: strings.TrimSpace(response.Header.Get("Content-Type")),
|
||||
BodyPreview: strings.Join(strings.Fields(strings.TrimSpace(string(body))), " "),
|
||||
}
|
||||
}
|
||||
|
||||
document, err := goquery.NewDocumentFromReader(response.Body)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -125,3 +126,35 @@ func TestFetchWatchOrder_MissingMarkupReturnsError(t *testing.T) {
|
||||
t.Fatalf("expected ErrWatchOrderMarkupNotFound, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchWatchOrder_HTTPStatusErrorIncludesContext(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Server", "cloudflare")
|
||||
w.Header().Set("CF-Ray", "abc123")
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
_, _ = w.Write([]byte("<html><body>access denied</body></html>"))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
url := server.URL + "/?/tools/watch_order/id/1"
|
||||
_, err := FetchWatchOrder(context.Background(), &http.Client{Timeout: time.Second}, url)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got nil")
|
||||
}
|
||||
|
||||
var statusError *HTTPStatusError
|
||||
if !errors.As(err, &statusError) {
|
||||
t.Fatalf("expected HTTPStatusError, got %T", err)
|
||||
}
|
||||
|
||||
if statusError.StatusCode != http.StatusForbidden {
|
||||
t.Fatalf("expected 403, got %d", statusError.StatusCode)
|
||||
}
|
||||
if statusError.CFRay != "abc123" {
|
||||
t.Fatalf("expected cf-ray abc123, got %q", statusError.CFRay)
|
||||
}
|
||||
if !strings.Contains(statusError.BodyPreview, "access denied") {
|
||||
t.Fatalf("expected body preview to include access denied, got %q", statusError.BodyPreview)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user