fix: WebDAV restore crash - _Map<String,dynamic> is not a subtype of ResponseBody? - #2360
fix: WebDAV restore crash - _Map<String,dynamic> is not a subtype of ResponseBody?#2360bighamx wants to merge 1 commit into
Conversation
Restore via WebDAV crashed on all platforms with: type '_Map<String, dynamic>' is not a subtype of type 'ResponseBody?' of 'value' Root cause: webdav_client 1.2.2 calls `wdReadWithStream` without a type argument on `req()`. T falls back to dynamic, and dio 5.x's `fetch<T>` then resets `responseType` to `ResponseType.json`, so the body is decoded into a Map and dio's `assureResponse<T>` (T=ResponseBody) fails the covariant cast. Backup works because it uses PUT (non-generic Response), only restore's GET path hits the ResponseBody assertion. Vendor webdav_client 1.2.2 into plugins/webdav_client_fork and pass the explicit `req<ResponseBody>` type argument so the stream responseType is kept and the cast no longer fails. No other logic changes.
29f4f1e to
de2d897
Compare
|
FlClash 的备份文件是一个 zip 压缩包,下载文件的响应体能够被识别为 json,并且转换为 |
两点回应。 1. “响应体能转成 Map”恰好证明了根因在 webdav_client,而不是像你说的“响应体本身有问题”
两种情况都指向同一个代码缺陷:二进制下载被强制 JSON 解析,而且它把真实的 HTTP 错误(401/502/网关 JSON 错误体)包装成一个看不懂的类型错抛出来。 2. 备份成功、恢复必崩,说明这是客户端类型层的问题,与你的服务器/网络无关 备份走 修复给 所以结论是:你观察到“响应体型态像 JSON”的现象没错,但它恰好是客户端错误地把下载当 JSON 做的直接证据,修复目标正是在这条链上,不依赖任何服务器行为。 |
What this fixes
WebDAV restore crashes on all platforms (Windows / Android) right after a successful backup:
Root cause
This is not a bug in FlClash's business code — it is a type-incompatibility between the
webdav_clientdependency (v1.2.2) and Dio 5.x.Restore goes through
webdav_client'sread2File()→wdReadWithStream(), which does:req<T>is called without an explicit type, soTresolves todynamicand propagates into Dio'srequestUri<T>. In today's Dio 5.x,fetch<T>then resetsRequestOptions.responseTypetoResponseType.json— so the response body is decoded into aMap<String, dynamic>, whilewdReadWithStreamdeclares the variable asResponse<ResponseBody>. Dio 5.x'sassureResponse<T>finally performs the covariant castresponse.data as T?(T = ResponseBody), which throws the reported error.Backup succeeds because it uses PUT (
wdWriteWithStream), whoserespis a non-genericResponseand never hits theResponseBodycovariance assertion. So all three clients share the same single dependency bug — not three separate ones.Fix
webdav_clientupstream (1.2.2) is unmaintained with no newer release, so this PR vendors it the way the repo already vendors other plugins (plugins/proxy,plugins/window_ext, ...):plugins/webdav_client_fork/— a copy ofwebdav_client1.2.2 with a one-line change inlib/src/webdav_dio.dart:responseType: stream(no JSON fallback), so theResponseBodycovariance cast no longer fails.pubspec.yaml—webdav_clientnow points at the local fork viapath:.The only functional change is the added generic type argument; everything else in the vendored package is byte-for-byte the upstream 1.2.2 source.
Testing
The only code change is the added generic type argument (verified against dio's
fetch<T>/assureResponse<T>source). I could not runflutter analyze/flutter testin this environment (no Flutter SDK available), so a CI re-run on this branch would be valuable before merge.