Repository navigation
This release fixes several bugs that affected real applications and adds
request cancellation. Most apps need no code changes; see "Behavior changes"
below. Note that ^0.0.2 does not allow 0.0.3; update your constraint to
^0.0.3.
Bug fixes
- Typed requests work.
request<Map<String, dynamic>>(and anyTother
thandynamic) threw aTypeErroron every adapter, after sending extra
retry requests. Responses are now converted toApiResponse<T>; data of
the wrong type throws aSerializationExceptionwith a clear message. HttpAdapter: HTTP error statuses reachonError. Non-2xx responses
skipped the error interceptors, so 5xx/429 responses were never retried and
never served from stale cache.DioAdapter/RetrofitAdapter: ETag revalidation works. A304 Not Modifiedwas thrown as aServerExceptioninstead of serving the cached
data.- Builder timeouts are applied.
withConnectTimeout,withReceiveTimeout,
andwithSendTimeoutwere stored but ignored.HttpAdapteralso ignored
the per-request timeouts ofApiRequest. - Stale-while-revalidate is implemented.
enableStaleWhileRevalidatewas
accepted but had no effect. - Retries run in a single loop. Retries used to nest recursively, which
logged the final error once per attempt and over-counted
RetryMetrics.successfulRetries. - Retrofit retries. Retries created a new
Dioper attempt that was never
closed, dropped timeouts and response settings, and stopped after the
first failed retry. They now reuse the adapter's client. - Retrofit request changes. Changes interceptors make to the path,
method, query, body, timeouts, or removed headers now reach the request. HttpAdapterURLs. Absolute URLs inApiRequest.pathare supported,
and query strings in the path are merged withqueryParametersinstead of
being dropped.HttpAdapterbodies. JSON bodies are sent asapplication/json; they
were previously sent astext/plainunless aContent-Typewas given. Map
bodies withapplication/x-www-form-urlencodedare sent as form fields. A
body that cannot be JSON-encoded throwsSerializationException, and is no
longer retried as aNetworkException.HttpAdapterresponses respect the response charset and no longer fail
on invalid UTF-8.- Logger masking.
maskedKeysnow masks body fields (at any depth,
including JSON strings) and response headers, as documented. Before, only
request headers were masked, and passwords in bodies were logged in
plain text. Keys are matched case-insensitively on both sides. - The default
LoggerConfig.maskedKeysalso maskproxy-authorization,
cookie,set-cookie,x-api-key,api_key,access_token,
refresh_token, andclient_secret. - The logger never fails a request. Bodies that are not JSON-encodable
used to throw in JSON and curl output. - The logger printed error durations as
0:00:00.123000ms, and
requestFilterdid not apply to errors. RetryConfig.calculateDelayoverflowed to0for large attempt numbers,
and allowed negative custom delays.ApiRequest.hashCodediffered for equal requests with headers.CacheInterceptorthrew on very largemax-agevalues, cachedno-cache
responses without revalidation, did not renew entries after a304, and
did not count a miss when revalidating.CacheConfig.keyBuildernow receives the query string, so requests that
differ only by query parameters no longer share a cache entry.DioAdapteromitsnullquery parameters, likeHttpAdapter.MemoryCacheStorethrew formaxEntries <= 0.CacheKeyGenerator.generatethrew for query values that are not
JSON-encodable.
New
- Request cancellation:
ApiCancelTokenandApiRequest.cancelToken.
Cancelling aborts in-flight requests on every adapter, interrupts pending
retry delays, and throwsCancellationException, which is never retried.
One token can cancel many requests. WithRetrofitAdapter, Dio's
CancelTokennow also interrupts api_plus retry delays. HttpAdapterandDioAdapteracceptconnectTimeout,receiveTimeout,
andsendTimeout.- Accurate
HttpAdaptertimeouts: connect, send, and receive timeouts
now apply to the matching phase of the request, like Dio. The receive
timeout is an idle timeout between response chunks. Requests are aborted
when a timeout fires. MemoryCacheStore.evictionCount, andCacheMetrics.evictionsnow counts
MemoryCacheStoreLRU evictions.onResponseinterceptors now see error responses on every adapter (they
already did withHttpAdapter).
Behavior changes
- The minimum SDK is now Dart 3.4.
http ^1.6.0already required it, so the
previous>=3.1.0constraint could not be satisfied on older SDKs. - Non-
ApiExceptionerrors thrown by interceptors are propagated unchanged.
They are no longer wrapped inNetworkExceptionand retried. HttpAdapterreturns non-JSON content types (e.g.text/plain) as
Stringinstead of attempting to JSON-decode them, matching Dio.RetryConfig.onRetryis called before the delay, as documented.ServerExceptionmessages are the same on every adapter:
Server returned <status>: <reason>.
Documentation and tooling
- README rewritten: pipeline semantics, typed responses, timeouts, cache keys
and user-specific data, platform setup (macOS entitlements, Android
permission), limitations, and migration notes. - Adapter integration tests against a real local server, plus regression
tests for the fixes above. - CI tests on the real minimum SDK (3.4.0), checks the lowest dependency
versions, and runs ondevelop. - Removed unused dev dependencies (
mocktail,fake_async).