fix: log watch-order parse fallback

This commit is contained in:
2026-04-11 22:16:32 +02:00
parent 197c9c7485
commit f38ab058e0
3 changed files with 35 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ package jikan
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"strings" "strings"
"time" "time"
@@ -48,6 +49,7 @@ func (c *Client) getWatchOrder(ctx context.Context, id int) (watchorder.WatchOrd
result, err := watchorder.FetchWatchOrder(requestCtx, c.httpClient, watchOrderURL) result, err := watchorder.FetchWatchOrder(requestCtx, c.httpClient, watchOrderURL)
if err != nil { if err != nil {
log.Printf("relations: watch-order fetch failed for %d (%s): %v", id, watchOrderURL, err)
return watchorder.WatchOrderResult{}, err return watchorder.WatchOrderResult{}, err
} }
@@ -72,6 +74,7 @@ func (c *Client) currentOnlyRelation(ctx context.Context, id int) ([]RelationEnt
func (c *Client) GetFullRelations(ctx context.Context, id int) ([]RelationEntry, error) { func (c *Client) GetFullRelations(ctx context.Context, id int) ([]RelationEntry, error) {
result, err := c.getWatchOrder(ctx, id) result, err := c.getWatchOrder(ctx, id)
if err != nil { if err != nil {
log.Printf("relations: using current-only fallback for %d: %v", id, err)
return c.currentOnlyRelation(ctx, id) return c.currentOnlyRelation(ctx, id)
} }
@@ -93,6 +96,7 @@ func (c *Client) GetFullRelations(ctx context.Context, id int) ([]RelationEntry,
anime, err := c.GetAnimeByID(ctx, watchOrderEntry.ID) anime, err := c.GetAnimeByID(ctx, watchOrderEntry.ID)
if err != nil { if err != nil {
log.Printf("relations: skipping related anime %d for root %d: %v", watchOrderEntry.ID, id, err)
continue continue
} }

View File

@@ -17,6 +17,7 @@ const defaultUserAgent = "anime-relations-scraper/1.0 (+https://github.com/mkelv
var idPattern = regexp.MustCompile(`/id/(\d+)`) var idPattern = regexp.MustCompile(`/id/(\d+)`)
var ErrInvalidWatchOrderURL = errors.New("invalid watch order url") var ErrInvalidWatchOrderURL = errors.New("invalid watch order url")
var ErrWatchOrderMarkupNotFound = errors.New("watch order markup not found")
type WatchOrderEntry struct { type WatchOrderEntry struct {
ID int `json:"id"` ID int `json:"id"`
@@ -150,6 +151,10 @@ func extractRows(doc *goquery.Document) []watchOrderRow {
return rows return rows
} }
func hasWatchOrderTable(doc *goquery.Document) bool {
return doc.Find("#wo_list").Length() > 0
}
func FetchWatchOrder(ctx context.Context, httpClient *http.Client, url string) (WatchOrderResult, error) { func FetchWatchOrder(ctx context.Context, httpClient *http.Client, url string) (WatchOrderResult, error) {
rootID, err := parseRootID(url) rootID, err := parseRootID(url)
if err != nil { if err != nil {
@@ -161,6 +166,10 @@ func FetchWatchOrder(ctx context.Context, httpClient *http.Client, url string) (
return WatchOrderResult{}, err return WatchOrderResult{}, err
} }
if !hasWatchOrderTable(doc) {
return WatchOrderResult{}, ErrWatchOrderMarkupNotFound
}
rows := extractRows(doc) rows := extractRows(doc)
if len(rows) == 0 { if len(rows) == 0 {
return WatchOrderResult{ID: rootID, WatchOrder: []WatchOrderEntry{}}, nil return WatchOrderResult{ID: rootID, WatchOrder: []WatchOrderEntry{}}, nil

View File

@@ -2,6 +2,7 @@ package watchorder
import ( import (
"context" "context"
"errors"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
@@ -52,6 +53,16 @@ func testHTMLEmptyRows() string {
</html>` </html>`
} }
func testHTMLWithoutWatchOrderTable() string {
return `
<!doctype html>
<html>
<body>
<p>challenge page</p>
</body>
</html>`
}
func TestFetchWatchOrder_OutputShape(t *testing.T) { func TestFetchWatchOrder_OutputShape(t *testing.T) {
server := testServer(testHTMLWithMetadata()) server := testServer(testHTMLWithMetadata())
defer server.Close() defer server.Close()
@@ -103,3 +114,14 @@ func TestFetchWatchOrder_NoRowsReturnsEmpty(t *testing.T) {
t.Fatalf("expected no entries, got %d", len(result.WatchOrder)) t.Fatalf("expected no entries, got %d", len(result.WatchOrder))
} }
} }
func TestFetchWatchOrder_MissingMarkupReturnsError(t *testing.T) {
server := testServer(testHTMLWithoutWatchOrderTable())
defer server.Close()
url := server.URL + "/?/tools/watch_order/id/1535"
_, err := FetchWatchOrder(context.Background(), &http.Client{Timeout: time.Second}, url)
if !errors.Is(err, ErrWatchOrderMarkupNotFound) {
t.Fatalf("expected ErrWatchOrderMarkupNotFound, got %v", err)
}
}