exception.dart 3.71 KB
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

import 'api_response/api_response_entity.dart';

class ApiException implements Exception {
  static const unknownException = "未知错误";
  static const customErrorCode = -1;
  final String? message;
  final int? code;
  String? stackInfo;

  ApiException([this.code, this.message]);

  factory ApiException.fromDioException(DioException exception) {
    if (kDebugMode) {
      print('fromDioException 异常: $exception');
    }
    switch (exception.type) {
      case DioExceptionType.connectionTimeout:
        return BadRequestException(customErrorCode, "连接超时");
      case DioExceptionType.sendTimeout:
        return BadRequestException(customErrorCode, "请求超时");
      case DioExceptionType.receiveTimeout:
        return BadRequestException(customErrorCode, "响应超时");
      case DioExceptionType.badCertificate:
        return BadRequestException(customErrorCode, "证书错误");
      case DioExceptionType.badResponse:
        return BadRequestException(customErrorCode, "返回错误");
      case DioExceptionType.cancel:
        return BadRequestException(customErrorCode, "请求取消");
      case DioExceptionType.connectionError:
        return BadRequestException(customErrorCode, "连接错误");
      case DioExceptionType.unknown:
        int? errCode = exception.response?.statusCode;
        switch (errCode) {
          case 400:
            return BadRequestException(errCode, "请求语法错误");
          case 401:
            return UnauthorisedException(errCode, "没有权限");
          case 403:
            return UnauthorisedException(errCode, "服务器拒绝执行");
          case 404:
            return UnauthorisedException(errCode, "无法连接服务器");
          case 405:
            // 会出发登出的code,这里强制换掉
            return UnauthorisedException(406, "请求方法被禁止");
          case 500:
            return UnauthorisedException(errCode, "服务器内部错误");
          case 502:
            return UnauthorisedException(errCode, "无效的请求");
          case 503:
            return UnauthorisedException(errCode, "服务器异常");
          case 505:
            return UnauthorisedException(errCode, "不支持HTTP协议请求");
          default:

            /// 试一下Response能不能解析出业务上的错误码,不能再继续走dio抛出的异常
            try {
              ApiResponse apiResponse = ApiResponse.fromJson(exception.response?.data);
              if (apiResponse.code != null) {
                return ApiException(apiResponse.code, apiResponse.msg ?? "错误码:${apiResponse.code}");
              }
            } catch (e) {
              if (kDebugMode) {
                print('DioExceptionType.unknown 错误: $e');
              }
            }
        }
    }
    var errorCode = exception.response?.statusCode ?? customErrorCode;
    var errorMsg = kDebugMode ? (exception.response?.statusMessage ?? exception.message) : unknownException;
    return ApiException(errorCode, errorMsg);
  }

  factory ApiException.from(dynamic exception) {
    if (exception is DioException) {
      return ApiException.fromDioException(exception);
    }
    if (exception is ApiException) {
      return exception;
    }
    var apiException = ApiException(-1, unknownException);
    apiException.stackInfo = exception?.toString();
    return apiException;
  }
}

/// 请求错误
class BadRequestException extends ApiException {
  BadRequestException([int? code, String? message]) : super(code, message);
}

/// 未认证异常
class UnauthorisedException extends ApiException {
  UnauthorisedException([int? code, String? message]) : super(code, message);
}