使用 Dio/bloc Flutter 处理错误

Posted

技术标签:

【中文标题】使用 Dio/bloc Flutter 处理错误【英文标题】:Handling Errors with Dio/bloc Flutter 【发布时间】:2020-01-17 08:09:15 【问题描述】:

在使用 Dio 请求时,我需要一种处理错误的好方法。 我可以在一堂课上完成并通过 dio 请求 throw it 吗? 它应该返回带有错误的响应。

【问题讨论】:

【参考方案1】:

我在这里发布了我的通用网络集团,它可以在任何时间、任何地点重复使用。此外,它使用 dio 使用 API 存储库、异常和错误处理。

class NetworkBloc extends Bloc<NetworkEvent, NetworkState> 
  NetworkBloc() : super(NetworkRequestInitial());

  @override
  Stream<NetworkState> mapEventToState(
    NetworkEvent event,
  ) async* 
    yield NetworkRequestInitiated();
    if (event is NetworkCallEvent) 
      RequestType requestType = event.requestType;
      if (requestType == RequestType.GET) 
        yield* fetchData(event);
       else if (requestType == RequestType.POST) 
        yield* uploadDataAndStoreResult(event);
      
    
  

  Stream<NetworkState> fetchData(NetworkCallEvent event) async* 
    Response response;
    try 
      yield NetworkRequestLoading();
      response =
          await event.apiRepository.sendGetRequest(event.url, event.request);
      if (response.statusCode == 200) 
        yield NetworkRequestLoaded(response: response);
       else 
        Map jsonResponse = jsonDecode(response.data);
        yield NetworkRequestFailure(message: jsonResponse['message']);
      
     catch (e) 
      yield NetworkRequestFailure(
          message: NetworkUtils.getErrorMessageAccordingToError(e));
    
  

  Stream<NetworkState> uploadDataAndStoreResult(NetworkCallEvent event) async* 
    Response response;
    try 
      yield NetworkRequestLoading();
      if (event.request != null) 
        if (event.isHeadersNeeded) 
          response = await event.apiRepository.sendPostRequestWithHeader(
            event.url,
            request: event.request,
          );
         else 
          response = await event.apiRepository.sendPostRequest(
            event.url,
            event.request,
          );
        
       else 
        response = await event.apiRepository
            .sendPostRequestWithoutBodyParameters(event.url);
      
      if (response.statusCode == 200) 
        saveDataAccordingToCacheMechanism(event, response);
        yield NetworkRequestLoaded(response: response);
       else 
        Map jsonResponse = jsonDecode(response.data);
        yield NetworkRequestFailure(message: jsonResponse['message']);
      
     catch (e) 
      yield NetworkRequestFailure(
          message: NetworkUtils.getErrorMessageAccordingToError(e));
    
  

  void saveDataAccordingToCacheMechanism(
      NetworkCallEvent event, Response response) async 
    if (event.cacheMechanism == CacheMechanism.SharePreferences) 
      Hive.box(ConstUtils.dbName)
          .put(event.keyForSharedPreferences, response.data.toString());
     else if (event.cacheMechanism == CacheMechanism.Database) 
  

我还添加了状态和事件以使其更易于理解。

class NetworkCallEvent extends NetworkEvent 
  final String request;
  final dynamic url;
  final RequestType requestType;
  final CacheMechanism cacheMechanism;
  final String keyForSharedPreferences;
  final APIRepository apiRepository;
  final bool isHeadersNeeded;

  NetworkCallEvent(
      @required this.url,
      this.request,
      this.isHeadersNeeded = false,
      @required this.requestType,
      @required this.apiRepository,
      @required this.cacheMechanism,
      this.keyForSharedPreferences);

  @override
  List<Object> get props => [
        this.url,
        this.request,
        this.requestType,
        this.cacheMechanism,
        this.keyForSharedPreferences,
        this.apiRepository
      ];

Network_states:

class NetworkRequestInitial extends NetworkState 

class NetworkRequestInitiated extends NetworkState 

class NetworkRequestLoading extends NetworkState 

class NetworkRequestLoaded extends NetworkState 
  final dynamic response;

  NetworkRequestLoaded(this.response);

  @override
  List<Object> get props => [this.response];


class NetworkRequestFailure extends NetworkState 
  final String message;

  NetworkRequestFailure(this.message);

  @override
  List<Object> get props => [this.message];

您可以轻松地以 JSON 格式发送请求并获得动态响应,您可以使用 json.decode() 将其转换为适当的对象。

【讨论】:

以上是关于使用 Dio/bloc Flutter 处理错误的主要内容,如果未能解决你的问题,请参考以下文章

json.decode() 输入意外结束(在字符 1 处)

如何使用 Flutter 处理应用程序生命周期(在 Android 和 iOS 上)?

未处理的异常:FormatException:输入意外结束(在字符 1 处)

为最终用户处理 Flutter 上的 Firebase 身份验证错误

Flutter:未处理的异常:错误状态:调用关闭后无法添加新事件(不一样的情况)

Flutter初学 —— 常用控件使用