Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error while using #11

Closed
BB-fat opened this issue Oct 27, 2019 · 4 comments
Closed

Error while using #11

BB-fat opened this issue Oct 27, 2019 · 4 comments

Comments

@BB-fat
Copy link

BB-fat commented Oct 27, 2019

[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: DioError [DioErrorType.DEFAULT]: NoSuchMethodError: The method 'trim' was called on null.
Receiver: null
Tried calling: trim()
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 Headers.set (package:dio/src/headers.dart:61:27)
#2 Headers.add (package:dio/src/headers.dart:49:29)
#3 DioCacheManager._buildResponse. (package:dio_http_cache/src/manager_dio.dart:65:47)
#4 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
#5 DioCacheManager._buildResponse (package:dio_http_cache/src/manager_dio.dart:65:21)
#6 DioCacheManager._onError (package:dio_http_cache/src/manager_dio.dart:58:16)

#7 InterceptorsWrapper.onError (package:dio/src/interceptor.dart:125:14)

#8 DioMixin._request._errorInterceptorWrapper. (package:dio/src/dio.dart:846:40)

#9 _rootRunUn<…>

@BB-fat
Copy link
Author

BB-fat commented Oct 27, 2019

反复测试发现是在app启动后一段时间这部分异常,加了个try之后可以正常拿到body,header索性忽略了
Response _buildResponse(String data, RequestOptions options) {
var headers = Headers();
// 由于header这里在app启动的时候总抛出异常,所以加一层try忽略
try {
options.headers.forEach((k, v) => headers.add(k, v));
}catch(e){}
return Response(
data: (options.responseType == ResponseType.json)
? jsonDecode(data)
: data,
headers: headers,
extra: options.extra..remove(DIO_CACHE_KEY_MAX_AGE),
statusCode: 200);
}

@hurshi
Copy link
Owner

hurshi commented Oct 29, 2019

非常感谢你的反馈,但我这边并没有复现呢。
看了你的异常,应该是 header 中有一个 key 为 null, 而导致 crash。
不知你能提供下异常的环境不?方便的话,可以贴一下你请求的数据,比如:

var _dio = Dio(
  BaseOptions(
    baseUrl: "https://www.wanandroid.com/", 
    contentType: "application/x-www-form-urlencoded; charset=utf-8")
  )
  ..interceptors.add(_manager.interceptor)
  ..interceptors.add(LogInterceptor(responseBody: true));

void rq() {
  _dio.post(
      "www.baidu.com", 
      data: {'k': "keyword"}, 
      options: buildCacheOptions(Duration(hours: 1)))
  .then((response) {
      print(">>> ${response.data}");
  });
}

或者提供一个能重现 crash 的 demo 就更好了。

@BB-fat
Copy link
Author

BB-fat commented Oct 29, 2019

的确是这样的,我将dio封装了一下,一开始token默认为null然后返回认证失败的时候再请求token

//  刷新token
  Future _refreshToken() async {
    if (Global.debug) {
      token = "debug";
      return;
    }
    Dio d = Dio();
    d.interceptors.add(LogInterceptor(responseBody: false));
    Response res = await d.post(_baseurl + "/api/v1/auth/token",
        data: json.encode({"id": Global.id, "message": Global.aesKey}));
    if (res.statusCode == 403) {
      Global.id = Global.aesKey = null;
//      TODO 需要登陆时跳转到登陆界面
//      Navigator.popUntil(context, predicate)
    }
    token = res.data["token"];
  }

  Future get(String url,
      {Map<String, dynamic> params = null,
      Duration cacheTime = const Duration(days: 5),
      bool useCache = true}) async {
    Response res = await _dio.get(
      _baseurl + url,
      queryParameters: params,
      options: buildCacheOptions(cacheTime,
          forceRefresh: !useCache, options: Options(headers: {"Token": token})),
    );
    if (res.statusCode == 401) {
      await _refreshToken();
      return get(url, params: params, cacheTime: cacheTime, useCache: useCache);
    } else {
      return res;
    }
  }

所以app的第一次请求header里的token是null。

@hurshi
Copy link
Owner

hurshi commented Oct 29, 2019

Hi, 0.2.1 版本应该就没问题拉。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants