handleResponse<T> static method

BaseResponse<T> handleResponse<T>(
  1. Response response
)

处理响应数据

Implementation

static BaseResponse<T> handleResponse<T>(Response response) {
  try {
    final statusCode = TypeSafetyUtils.safeInt(response.statusCode, defaultValue: 0);

    // 处理标准HTTP错误 - 检查是否在成功状态码列表中
    final successCodes = HttpConfig.successCodes;
    if (!successCodes.contains(statusCode) && (statusCode < 200 || statusCode >= 300)) {
      throw AppException.httpError(statusCode);
    }

    // 安全地处理响应数据 - 使用类型安全的方式转换Map
    final json = TypeSafetyUtils.safeMap(response.data);

    // 如果成功转换为Map,说明是JSON响应
    if (json.isNotEmpty || response.data is Map) {
      // 使用类型安全的方式提取值
      int code = TypeSafetyUtils.safeInt(_extractIntField(json, _serviceCodeSet), defaultValue: 0);
      String message = TypeSafetyUtils.safeString(_extractStringField(json, _serviceMessageSet));
      String bizCode = TypeSafetyUtils.safeString(_extractStringField(json, _serviceBizCodeSet));
      String bizMessage = TypeSafetyUtils.safeString(_extractStringField(json, _serviceBizMessageSet));
      dynamic rawData = _extractField(json, _serviceDataSet);

      // 先检查HTTP状态码 - 使用配置的成功状态码列表
      if (!successCodes.contains(statusCode) && (statusCode < 200 || statusCode >= 300)) {
        throw AppException.httpError(statusCode);
      }

      // 再检查业务状态码
      final codes = HttpConfig.successCodes;
      String finalMessage = message;
      String? finalBizMessage = bizMessage.isNotEmpty ? bizMessage : null;

      if (codes.contains(code)) {
        // 业务成功 - 不需要国际化处理,直接使用服务器消息
        // 截断过长的消息,避免 Toast 显示过长内容
        finalMessage = truncateMessage(finalMessage);
      } else {
        // 业务失败 - 根据配置决定是否进行国际化处理
        String localMessage = finalMessage.isNotEmpty ? finalMessage : 'Unknown error';

        // 根据 errorMsgLocalizationStrategy 配置决定处理方式
        if (DomainConfig.errorMsgLocalizationStrategy == ErrorMsgLocalizationStrategy.localize) {
          // 使用本地化文件进行国际化
          try {
            final internationalizedMessage = ErrorCodeIntl.getMessage(
              bizCode.isNotEmpty ? bizCode : '',
              serverMessage: finalMessage,
            );
            if (internationalizedMessage.isNotEmpty) {
              localMessage = internationalizedMessage;
            }
          } catch (e) {
            // 国际化失败,继续使用服务器消息
            if (kDebugMode) {
              print('⚠️ 本地化获取失败,使用服务器消息: $e');
            }
          }
        } else {
          // 直接使用服务器返回的消息,不进行本地化处理
          if (kDebugMode) {
            print('🌍 使用服务器消息(不进行本地化): $finalMessage');
          }
        }

        // 截断过长的消息,避免 Toast 显示过长内容
        finalMessage = truncateMessage(localMessage);
        if (finalBizMessage != null && finalBizMessage.isNotEmpty) {
          finalBizMessage = truncateMessage(finalBizMessage);
        }
      }

      // 封装统一的响应结构(业务成功或失败都返回 BaseResponse)
      // BaseResponse 的 success 字段会根据 code 和 bizCode 自动判断
      return BaseResponse<T>(
          code: code,
          message: finalMessage,
          bizCode: bizCode.isNotEmpty ? bizCode : null,
          bizMessage: (finalBizMessage != null && finalBizMessage.isNotEmpty) ? finalBizMessage : null,
          data: rawData,
          originData: response.data);
    }

    // 非JSON响应直接返回
    return BaseResponse<T>(code: 200, message: 'OK', data: response.data, originData: response.data);
  } catch (e) {
    // 如果已经是 AppException(业务错误),直接重新抛出,不记录为解析错误
    if (e is AppException) {
      // 业务错误是预期的,不需要记录为解析错误
      rethrow;
    }

    // 以下是真正的解析错误
    if (kDebugMode) {
      print('⚠️ 响应解析错误: $e');
      print('错误类型: ${e.runtimeType}');
      print('响应状态码: ${response.statusCode}');
      print('响应数据类型: ${response.data.runtimeType}');
      print('响应数据内容: ${response.data}');
      if (e is Error) {
        print('错误堆栈: ${e.stackTrace}');
      } else if (e is Exception) {
        print('异常详情: ${e.toString()}');
      }
    }

    // 处理类型不匹配异常
    if (e is TypeError) {
      final statusCode = TypeSafetyUtils.safeInt(response.statusCode, defaultValue: 500);
      if (kDebugMode) {
        print('⚠️ 响应数据类型不匹配: ${e.toString()}');
        print('响应数据类型: ${response.data.runtimeType}');
        print('响应状态码: $statusCode');
        print('尝试转换的数据: ${response.data}');
      }
      throw AppException(
        code: statusCode,
        message: truncateMessage('响应数据格式错误,类型不匹配'),
        data: response.data,
      );
    }

    // 处理格式异常(如JSON解析错误)
    if (e is FormatException) {
      final statusCode = TypeSafetyUtils.safeInt(response.statusCode, defaultValue: 500);
      if (kDebugMode) {
        print('⚠️ 响应数据格式异常: ${e.message}');
        print('响应状态码: $statusCode');
        print('原始数据: ${response.data}');
      }
      throw AppException(
        code: statusCode,
        message: truncateMessage('响应数据格式错误: ${e.message}'),
        data: response.data,
      );
    }

    // 其他异常才转换为 HTTP 错误
    final statusCode = TypeSafetyUtils.safeInt(response.statusCode, defaultValue: 500);
    if (kDebugMode) {
      print('⚠️ 未知解析错误,转换为HTTP错误: $statusCode');
    }
    throw AppException.httpError(statusCode);
  }
}