p3: tavily parse errors degrade; retry DNS on search

A 200 with a bad Tavily body is tavily: error, not an empty success
that would cache for the hour. Upstream clients stay in the source
list if DNS is down at boot and retry the pin on Search; /healthz
lists them as unresolved until a pin lands.
This commit is contained in:
2026-09-23 12:22:31 -07:00
parent f748e695b1
commit 429f6b207e
8 changed files with 177 additions and 51 deletions
+11 -5
View File
@@ -17,6 +17,7 @@ type Tavily struct {
}
func (s *Tavily) Name() string { return NameTavily }
func (s *Tavily) Ready() bool { return s != nil && s.Client.Ready() }
type tavilyReq struct {
Query string `json:"query"`
@@ -31,7 +32,9 @@ func (s *Tavily) Search(ctx context.Context, query string, k int) SourceOut {
if s == nil || s.Client == nil {
return SourceOut{Warn: NameTavily + ": error"}
}
_ = s.Client.RefreshIfStale(ctx)
if w := pinErr(ctx, s.Client, NameTavily); w != "" {
return SourceOut{Warn: w}
}
if k <= 0 {
k = DefaultK
}
@@ -66,11 +69,14 @@ func (s *Tavily) Search(ctx context.Context, query string, k int) SourceOut {
if err != nil {
return SourceOut{Warn: warnErr(NameTavily, err)}
}
hits, credits := mapTavily(raw)
hits, credits, err := mapTavily(raw)
if err != nil {
return SourceOut{Warn: NameTavily + ": error"}
}
return SourceOut{Hits: hits, Credits: credits}
}
func mapTavily(raw []byte) ([]Hit, int) {
func mapTavily(raw []byte) ([]Hit, int, error) {
var env struct {
Answer string `json:"answer"`
Results []struct {
@@ -84,7 +90,7 @@ func mapTavily(raw []byte) ([]Hit, int) {
} `json:"usage"`
}
if err := json.Unmarshal(raw, &env); err != nil {
return nil, 0
return nil, 0, err
}
_ = env.Answer // dropped; never returned
hits := make([]Hit, 0, len(env.Results))
@@ -98,5 +104,5 @@ func mapTavily(raw []byte) ([]Hit, int) {
if credits <= 0 {
credits = 1
}
return hits, credits
return hits, credits, nil
}