call static method
Future<void>
call(
- String url,
- RequestType requestType, {
- Map<
String, dynamic> ? headers, - Map<
String, dynamic> ? queryParameters, - required dynamic onSuccess(
- Response response
- dynamic onError(
- ApiException error
- dynamic onReceiveProgress()?,
- dynamic onSendProgress()?,
- Function? onLoading,
- CancelToken? cancelToken,
- dynamic data,
perform safe api request
Implementation
static Future<void> call(
String url,
RequestType requestType, {
Map<String, dynamic>? headers,
Map<String, dynamic>? queryParameters,
required Function(Response response) onSuccess,
Function(ApiException error)? onError,
Function(int value, int progress)? onReceiveProgress,
Function(int total, int progress)?
onSendProgress, // while sending (uploading) progress
Function? onLoading,
CancelToken? cancelToken,
dynamic data,
}) async {
try {
// 1) indicate loading state
await onLoading?.call();
// 2) try to perform http request
late Response response;
if (requestType == RequestType.get) {
response = await _dio.get(
url,
onReceiveProgress: onReceiveProgress,
queryParameters: queryParameters,
options: Options(headers: headers),
);
} else if (requestType == RequestType.post) {
response = await _dio.post(
url,
data: data,
onReceiveProgress: onReceiveProgress,
onSendProgress: onSendProgress,
queryParameters: queryParameters,
options: Options(headers: headers),
cancelToken: cancelToken,
);
} else if (requestType == RequestType.put) {
response = await _dio.put(
url,
data: data,
onReceiveProgress: onReceiveProgress,
onSendProgress: onSendProgress,
queryParameters: queryParameters,
options: Options(headers: headers),
);
} else if (requestType == RequestType.patch) {
response = await _dio.patch(
url,
data: data,
onReceiveProgress: onReceiveProgress,
onSendProgress: onSendProgress,
queryParameters: queryParameters,
options: Options(headers: headers),
);
} else {
response = await _dio.delete(
url,
data: data,
queryParameters: queryParameters,
options: Options(headers: headers),
);
}
await onSuccess(response);
} on DioException catch (error) {
final _RetryableApiCall retryable = _RetryableApiCall(
url: url,
requestType: requestType,
headers: headers == null ? null : Map<String, dynamic>.from(headers),
queryParameters: queryParameters == null
? null
: Map<String, dynamic>.from(queryParameters),
data: data,
);
final int? statusCode = error.response?.statusCode;
if (statusCode == 401) {
_track401FailedCall(retryable);
// If the host already updated the token shortly before this late 401,
// immediately retry once instead of waiting for another refresh.
final bool hasActiveGate = _authRefreshCompleter != null;
final bool tokenUpdatedRecently = _lastAuthTokenUpdatedAt != null &&
DateTime.now().difference(_lastAuthTokenUpdatedAt!) <
_authRefreshWaitTimeout;
if (!hasActiveGate && tokenUpdatedRecently) {
try {
final Response retryResponse = await _executeRequestForRetry(
url,
requestType,
headers: headers,
queryParameters: queryParameters,
data: data,
onReceiveProgress: onReceiveProgress,
onSendProgress: onSendProgress,
cancelToken: cancelToken,
);
_untrack401FailedCall(retryable);
await onSuccess(retryResponse);
return;
} on DioException catch (lateError) {
final int? lateStatusCode = lateError.response?.statusCode;
if (lateStatusCode == 401) {
// Token is still not accepted; fall back to the normal gate
// flow (which will emit a new authError cycle if needed).
} else {
_handleDioError(error: lateError, url: url, onError: onError);
return;
}
}
}
await _handleAuth401AndRetry(
error: error,
url: url,
requestType: requestType,
headers: headers,
queryParameters: queryParameters,
data: data,
onReceiveProgress: onReceiveProgress,
onSendProgress: onSendProgress,
cancelToken: cancelToken,
onSuccess: onSuccess,
onError: onError,
trackedCall: retryable,
);
return;
}
_handleDioError(error: error, url: url, onError: onError);
} on SocketException {
_handleSocketException(url: url, onError: onError);
} on TimeoutException {
_handleTimeoutException(url: url, onError: onError);
} catch (error) {
_handleUnexpectedException(url: url, onError: onError, error: error);
}
}