makeTrayRequest<ModelType> function

Future<TrayRequestResponse<ModelType>> makeTrayRequest<ModelType>(
  1. TrayRequest request, {
  2. Dio? client,
  3. FetchTrayDebugLevel? requestDebugLevel,
})

makes the process of requesting data from an api endpoint easier it takes care of making the request and mocking

Implementation

Future<TrayRequestResponse<ModelType>> makeTrayRequest<ModelType>(
  TrayRequest request, {
  Dio? client,
  FetchTrayDebugLevel? requestDebugLevel,
}) async {
  final clientToUse = client ?? FetchTray.instance.dio;
  Response response = Response(
    requestOptions: RequestOptions(
      path: request.url,
    ),
  );

  try {
    final pluginRequestExtra = FetchTray.instance.plugins.map(
      (plugin) => plugin.getRequestExtra(request),
    );
    Map<String, dynamic> mergedRequestExtra = {};

    if (pluginRequestExtra.isNotEmpty) {
      mergedRequestExtra =
          pluginRequestExtra.reduce((value, element) => value..addAll(element));
    }

    final options = Options(
      method: request.method.toString().split('.').last,
      headers: await request.getHeaders(),
      extra: mergedRequestExtra,
    );

    // if in debug mode (at least FetchTrayDebugLevel.everything) -> log
    logRequest(
      message:
          '---------------------------------- \nStarting FetchTray Request (${request.getUrlWithParams()})',
      logType: FetchTrayLogLevel.info,
      requestDebugLevel: requestDebugLevel,
      request: request,
    );

    response = await clientToUse.request(
      await request.getUrlWithParams(),
      data: await request.getBody(),
      options: options,
    );

    // if in debug mode (at least FetchTrayDebugLevel.everything) -> log
    logRequest(
      message: 'FetchTray Response (${request.getUrlWithParams()})',
      logType: FetchTrayLogLevel.info,
      requestDebugLevel: requestDebugLevel,
      request: request,
      response: response,
    );

    try {
      final trayRequestResponse = TrayRequestResponse<ModelType>(
        data: request.getModelFromJson(
          response.data,
        ),
        dataRaw: response.data,
      );

      // call after success hook
      request.afterSuccess(trayRequestResponse);

      // return it
      return Future.value(trayRequestResponse);
    } catch (e, st) {
      throw JsonConversionException(e.toString(), st);
    }
  } on DioException catch (e) {
    // log error
    logRequest(
      message:
          'FETCH TRAY EXCEPTION: Api returned the status error code ${e.response?.statusCode ?? 500}',
      logType: FetchTrayLogLevel.error,
      requestDebugLevel: requestDebugLevel,
      request: request,
      response: e.response,
    );

    if (e.response != null) {
      return TrayRequestResponse(
        error: request.getEnvironment().parseErrorDetails(
              request,
              e.response!,
              e.response!.data,
            ),
      );
    } else {
      logRequest(
        message:
            'FETCH TRAY EXCEPTION: Something happened in setting up or sending the request that triggered an error.',
        logType: FetchTrayLogLevel.error,
        requestDebugLevel: requestDebugLevel,
        request: request,
        response: e.response,
      );

      return TrayRequestResponse<ModelType>(
        error: TrayRequestError(
          message: e.message ?? 'Unexpected error',
          errors: null,
          statusCode: 500,
        ),
      );
    }
  } on JsonConversionException catch (err) {
    logRequest(
      message:
          'FETCH TRAY EXCEPTION: Could not convert the code to json! ${err.toString()}',
      logType: FetchTrayLogLevel.error,
      requestDebugLevel: requestDebugLevel,
      request: request,
    );

    return TrayRequestResponse<ModelType>(
      error: request.getEnvironment().parseErrorDetails(
        request,
        response,
        {
          'message': err.message,
        },
        debugInfo: {
          'stackTrace': err.stackTrace,
          'debugHint':
              'FetchTray result could not be converted! Please check whether the result was really a json entity representing the model. (${err.toString()})',
          'resultBody': response.data,
        },
      ),
    );
  } catch (err, stackTrace) {
    logRequest(
      message: 'FETCH TRAY EXCEPTION: ${err.toString()}',
      logType: FetchTrayLogLevel.error,
      requestDebugLevel: requestDebugLevel,
      request: request,
      response: response,
      stackTrace: stackTrace,
    );

    // If there was another exception
    // then throw an exception.
    return TrayRequestResponse<ModelType>(
      error: request.getEnvironment().parseErrorDetails(
        request,
        response,
        {},
        debugInfo: {
          'resultBody': response.data,
        },
      ),
    );
  }
}