github reactiveui/refit v11.0.0
11.0.0

4 hours ago

⚠️ This is a breaking release (major: 10.x → 11.0.0)

11.0.0 reworks Refit's error/exception model and tightens interface validation. Most apps will compile, but code that inspects ApiResponse.Error, reads StatusCode, or catches transport exceptions around Refit calls will need changes. These are the same breaking changes that briefly shipped in the now‑delisted 10.1.7 and were reported by the community in #2114.

💡 Need a drop‑in, non‑breaking replacement for 10.1.6? Use 10.2.0 — it is 10.1.6 re‑signed with a valid certificate (the 10.1.6 cert was revoked, see #2114). Move to 11.0.0 when you're ready to adopt the changes below.

💥 What changed & how to migrate

1. ApiResponse<T>.Error is now ApiExceptionBase? (was ApiException?) (#2052)
A new abstract base ApiExceptionBase now sits under both ApiException and the new ApiRequestException. ApiExceptionBase does not expose Content / HasContent — those still live on ApiException.

// before
string? body = response.Error?.Content;

// after — narrow to ApiException first
if (response.Error is ApiException apiEx)
{
    string? body = apiEx.Content;   // Content/HasContent are on ApiException
}

2. New ApiRequestException wraps transport/connection failures (#2052)
Exceptions thrown by HttpClient.SendAsync before a response arrives — HttpRequestException (DNS/host unreachable), TaskCanceledException (timeouts), etc. — are now wrapped in ApiRequestException : ApiExceptionBase, carrying the full request context. For ApiResponse<T> return types these are now surfaced via .Error instead of only being thrown, so you no longer need a separate try/catch and IsSuccessful check.

// catching transport errors: catch the base (or ApiRequestException) now
catch (ApiExceptionBase ex) { /* covers ApiException + ApiRequestException */ }

3. ApiResponse<T>.StatusCode is now nullable (HttpStatusCode?) (#2052)
When the request never reached the server there is no status code. Code that assumed a non‑null value must handle null:

int code = (int)response.StatusCode;          // ❌ won't compile / may throw
int? code = (int?)response.StatusCode;         // ✅ handle the no-response case

4. Stricter interface validation + enum name handling (#2068)
Synchronous return types are now only permitted for generated/non‑public interface members (RestMethodInfo enforces the rule), and the System.Text.Json enum converter now maps serialized names both ways (including JsonStringEnumMemberName on .NET 9+). Interfaces that previously relied on unsupported sync members may now fail generation.


🗞️ What's Changed

✨ Features & Enhancements

⚡ Performance

  • Replace Activator.CreateInstance with direct constructor in ApiResponse.Create by @james-s-tayler in #2071
  • Avoid extra allocations when deserializing with Newtonsoft.Json by @yzhoholiev in #2085

🐛 Fixes

🧹 General & Housekeeping

📦 Dependencies

🙌 New Contributors

💖 Contributions

Thanks to everyone who contributed: @ChrisPulman, @PressXtoChris, @james-s-tayler, @yzhoholiev, @dyatlov-a

🤖 Automated services that contributed: @renovate[bot]

🔗 Full Changelog: v10.2.0...v11.0.0

Don't miss a new refit release

NewReleases is sending notifications on new releases.