fetch<Success> function
Future<Response<Success> >
fetch<Success>(
- Request<
Success> req, { - Dio? dio,
- CancelToken? cancelToken,
- ProgressCallback? onSendProgress,
- ProgressCallback? onReceiveProgress,
Implementation
Future<Response<Success>> fetch<Success>(
Request<Success> req, {
dio_package.Dio? dio,
dio_package.CancelToken? cancelToken,
dio_package.ProgressCallback? onSendProgress,
dio_package.ProgressCallback? onReceiveProgress,
}) async {
int startAgainLimit = 10;
while (startAgainLimit > 0) {
Response? res;
int limit;
RequestInterceptor<dynamic>? requestInterceptor = req.requestInterceptor;
limit = 10;
while (limit > 0 && requestInterceptor != null) {
try {
RequestInterceptorFlow flow = await requestInterceptor.interceptor.call(req);
if (flow.terminate) {
res = flow.response!;
}
req = flow.request as Request<Success>;
requestInterceptor = requestInterceptor.next;
} on ResponseCustomError catch (e) {
return ResponseCustomError(
message: e.message,
body: e.body,
error: e.error,
statusCode: e.statusCode,
headers: e.headers,
);
}
limit--;
}
if (res == null) {
int id = _requestRunningId++;
String url = req.isIncludeBaseUrl == true ? '${req.baseUrl}${req.url}' : '${req.url}';
final queryParamsString = req.queryParametersString;
final fullUrl = url.contains('?') ? '$url&$queryParamsString' : '$url?$queryParamsString';
sysLog.i('($id) >>> network request: [${req.method}] $fullUrl\n'
' body: ${req.body}\n'
' headers: ${req.headers}');
dio ??= dio_package.Dio();
cancelToken ??= dio_package.CancelToken();
try {
dio_package.Response<String> dioResponse = await dio.request<String>(
fullUrl,
data: req.body?.getBody(),
options: dio_package.Options(
method: req.method,
headers: req.headers,
validateStatus: (int? status) => status != null,
),
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
res = Response<String>(
data: dioResponse.data,
body: dioResponse.data,
statusCode: dioResponse.statusCode ?? 0,
headers: dioResponse.headers.map,
);
} on dio_package.DioError catch (e) {
cancelToken.cancel();
res = _getResponseByDioError(e);
}
sysLog.i('($id) <<< network response: statusCode=${res.statusCode}\n'
' header: ${res.headers}\n'
' body: ${res.body}\n');
}
ResponseInterceptor<dynamic>? responseInterceptor = req.responseInterceptor;
limit = 10;
bool startAgain = false;
while (limit > 0 && responseInterceptor != null) {
try {
var responseFlow = await responseInterceptor.interceptor(res!);
if (responseFlow.terminate) {
var r = Response.copyWith<Success>(
responseFlow.response,
message: responseFlow.response.message,
body: responseFlow.response.body,
statusCode: responseFlow.response.statusCode,
headers: responseFlow.response.headers,
data: responseFlow.response.data,
error: responseFlow.response.error,
extra: responseFlow.response.extra,
);
return r;
}
if (responseFlow.requestDecorator != null) {
req = responseFlow.requestDecorator!.call(req) as Request<Success>;
}
if (responseFlow.startAgain) {
startAgain = true;
break;
}
res = responseFlow.response;
responseInterceptor = responseInterceptor.next;
} on ResponseCustomError catch (r) {
return Response.copyWith<Success>(
r,
message: r.message,
body: r.body,
error: r.error,
extra: r.extra,
statusCode: r.statusCode,
headers: r.headers,
);
}
limit--;
}
if (startAgain) {
startAgainLimit--;
continue;
}
if (res == null) throw StateError('response is null state');
try {
Response<Success> finalResponse = Response.copyWith<Success>(
res,
message: res.message,
body: res.body,
data: req.mappingResponse?.call(res.data, res) ?? res.data,
error: res.error,
extra: res.extra,
statusCode: res.statusCode,
headers: res.headers,
);
return finalResponse;
} on ResponseCustomError catch (e) {
return ResponseCustomError(
message: e.message,
body: e.body,
error: e.error,
extra: e.extra,
statusCode: e.statusCode,
headers: e.headers,
);
} catch (e, s) {
String errorMessage = 'network response mapping fail: cannot parse "${res.data}" to model "$Success"';
sysLog.w(errorMessage);
return ResponseMappingFail(
message: errorMessage,
body: res.body,
error: res.error,
extra: res.extra,
statusCode: res.statusCode,
headers: res.headers,
);
}
}
throw Exception('startAgainLimit');
}