Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed
- **Cover-image lookup no longer 500s when one upstream metadata source returns a partial envelope:** `ImagesController.GetImage`'s fallback metadata-driven cover path accesses `env.metadata` on `GetMetadataAsync`'s `object?` return via the C# `dynamic` binder. When the returned envelope shape lacks a `metadata` property — which happens when one of the upstream sources (e.g., Audnexus) 500s and the service still returns a partial envelope — the binder throws `RuntimeBinderException`. That exception wasn't in `IsRecoverableImageLookupException`'s whitelist, so it bypassed the inner catch and the entire image endpoint returned 500. Adding `RuntimeBinderException` to the recoverable list lets the inner catch swallow the bad envelope and the lookup falls through to the next candidate URL or a placeholder, matching how the other recoverable failures behave.

## [0.2.71] - 2026-04-17

### Added
Expand Down
11 changes: 10 additions & 1 deletion listenarr.api/Controllers/ImagesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,16 @@ or ArgumentException
or FormatException
or UriFormatException
or System.Net.Http.HttpRequestException
or System.Text.Json.JsonException;
or System.Text.Json.JsonException
// GetMetadataAsync returns object?, and the fallback metadata path
// accesses fields via dynamic. When the returned envelope shape
// lacks the expected `metadata` property (e.g., when one of the
// upstream sources like Audnexus 500s and the service still
// returns a partial envelope), the C# dynamic binder throws
// RuntimeBinderException. Without this in the recoverable filter,
// a single bad envelope shape bubbles up to the outer catch and
// turns the whole image lookup into a 500.
or Microsoft.CSharp.RuntimeBinder.RuntimeBinderException;
}

private static string ResolvePathWithOptionalBase(string? basePath, string candidatePath)
Expand Down