mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-31 15:37:51 +01:00
fix(artwork): trace an external tier that never reaches an agent
A configured 'external' token vanished from the chain when no enabled agent provided images for that entity type, and for synthetic artists, leaving the trace unable to say whether the tier was even considered.
This commit is contained in:
parent
8458522dc5
commit
18476ff811
3 changed files with 54 additions and 2 deletions
|
|
@ -47,10 +47,17 @@ func fetchArtistImage(ctx context.Context, ag *agents.Agents, gate gateFunc, ar
|
|||
// Synthetic artists would otherwise get an unrelated agent result assigned to them.
|
||||
switch ar.ID {
|
||||
case consts.UnknownArtistID, consts.VariousArtistsID:
|
||||
traceFrom(ctx).add(traceStep{Candidate: externalCandidate, Outcome: outcomeSkipped, Detail: "synthetic artist"})
|
||||
return nil, "", false
|
||||
}
|
||||
name := externalName(ar.Name)
|
||||
for _, a := range ag.ArtistImageAgents() {
|
||||
imageAgents := ag.ArtistImageAgents()
|
||||
if len(imageAgents) == 0 {
|
||||
traceFrom(ctx).add(traceStep{Candidate: externalCandidate, Outcome: outcomeSkipped,
|
||||
Detail: "no enabled agent provides artist images"})
|
||||
return nil, "", false
|
||||
}
|
||||
for _, a := range imageAgents {
|
||||
reader, _, err := gate(a.Name, func() (io.ReadCloser, string, error) {
|
||||
imgs, err := a.Retriever.GetArtistImages(ctx, ar.ID, name, ar.MbzArtistID)
|
||||
if err != nil {
|
||||
|
|
@ -76,7 +83,13 @@ func fetchArtistImage(ctx context.Context, ag *agents.Agents, gate gateFunc, ar
|
|||
// fetchAlbumImage is the album counterpart of fetchArtistImage.
|
||||
func fetchAlbumImage(ctx context.Context, ag *agents.Agents, gate gateFunc, al model.Album) (r io.ReadCloser, agentName string, extErr bool) {
|
||||
name, artist := externalName(al.Name), externalName(al.AlbumArtist)
|
||||
for _, a := range ag.AlbumImageAgents() {
|
||||
imageAgents := ag.AlbumImageAgents()
|
||||
if len(imageAgents) == 0 {
|
||||
traceFrom(ctx).add(traceStep{Candidate: externalCandidate, Outcome: outcomeSkipped,
|
||||
Detail: "no enabled agent provides album images"})
|
||||
return nil, "", false
|
||||
}
|
||||
for _, a := range imageAgents {
|
||||
reader, _, err := gate(a.Name, func() (io.ReadCloser, string, error) {
|
||||
imgs, err := a.Retriever.GetAlbumImages(ctx, name, artist, al.MbzAlbumID)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -173,6 +173,30 @@ var _ = Describe("agent images", func() {
|
|||
Expect(a.artistCalls).To(Equal(0), "synthetic artists never reach the agents")
|
||||
})
|
||||
|
||||
It("records a skipped external candidate when no agent provides artist images", func() {
|
||||
ag := imageAgents()
|
||||
t := &chainTrace{}
|
||||
|
||||
r, _, extErr := fetchArtistImage(withTrace(ctx, t), ag, passthroughGate, model.Artist{ID: "ar1"})
|
||||
Expect(r).To(BeNil())
|
||||
Expect(extErr).To(BeFalse())
|
||||
Expect(t.Steps()).To(Equal([]traceStep{{Candidate: "external", Outcome: outcomeSkipped,
|
||||
Detail: "no enabled agent provides artist images"}}),
|
||||
"a configured external token must never be silently absent from the chain")
|
||||
})
|
||||
|
||||
It("records a skipped external candidate for synthetic artists", func() {
|
||||
a := &fakeImageAgent{name: "agentA", imgs: []agents.ExternalImage{img("/a", 100)}}
|
||||
ag := imageAgents(a)
|
||||
t := &chainTrace{}
|
||||
|
||||
_, _, _ = fetchArtistImage(withTrace(ctx, t), ag, passthroughGate,
|
||||
model.Artist{ID: consts.VariousArtistsID, Name: "Various Artists"})
|
||||
Expect(t.Steps()).To(HaveLen(1))
|
||||
Expect(t.Steps()[0].Outcome).To(Equal(outcomeSkipped))
|
||||
Expect(t.Steps()[0].Detail).To(ContainSubstring("synthetic"))
|
||||
})
|
||||
|
||||
It("clears typographic characters from the query name unless preserving unicode", func() {
|
||||
conf.Server.DevPreserveUnicodeInExternalCalls = false
|
||||
a := &fakeImageAgent{name: "agentA"}
|
||||
|
|
@ -231,6 +255,18 @@ var _ = Describe("agent images", func() {
|
|||
Expect(a.albumCalls).To(Equal(1))
|
||||
})
|
||||
|
||||
It("records a skipped external candidate when no agent provides album images", func() {
|
||||
ag := imageAgents()
|
||||
t := &chainTrace{}
|
||||
|
||||
r, _, extErr := fetchAlbumImage(withTrace(ctx, t), ag, passthroughGate, model.Album{Name: "Album"})
|
||||
Expect(r).To(BeNil())
|
||||
Expect(extErr).To(BeFalse())
|
||||
Expect(t.Steps()).To(Equal([]traceStep{{Candidate: "external", Outcome: outcomeSkipped,
|
||||
Detail: "no enabled agent provides album images"}}),
|
||||
"a configured external token must never be silently absent from the chain")
|
||||
})
|
||||
|
||||
It("reports extErr when the only agent fails transiently", func() {
|
||||
a := &fakeImageAgent{name: "agentA", err: context.DeadlineExceeded}
|
||||
ag := imageAgents(a)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ const (
|
|||
outcomeNotReached = "not-reached"
|
||||
)
|
||||
|
||||
// externalCandidate labels the external tier itself, for the cases that never reach an agent.
|
||||
const externalCandidate = "external"
|
||||
|
||||
// traceStep is one candidate the priority chain considered.
|
||||
type traceStep struct {
|
||||
Candidate string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue