parse static method

Object? parse(
  1. QueryResult<Object?> result, [
  2. Exception handleException(
    1. Map<String, dynamic>
    )?
])

Returns an exception of the given result with handleException if it has the specified error code or null if no exception was found.

Implementation

static Object? parse(
  QueryResult result, [
  Exception Function(Map<String, dynamic>)? handleException,
]) {
  if (result.hasException) {
    if (result.exception == null) {
      return Exception('err_unknown'.l10n);
    }

    // If no exceptions lay in `linkException`, then it is `GraphQlException`.
    if (result.exception!.linkException == null) {
      // If `GraphQlException` contains `NOT_CHAT_MEMBER` code, then it's a
      // specific `NotChatMemberException`.
      if (result.exception!.graphqlErrors.firstWhereOrNull(
            (e) => e.extensions?['code'] == 'NOT_CHAT_MEMBER',
          ) !=
          null) {
        return NotChatMemberException(result.exception!.graphqlErrors);
      } else if (result.exception!.graphqlErrors.firstWhereOrNull(
            (e) => e.extensions?['code'] == 'STALE_VERSION',
          ) !=
          null) {
        // If `GraphQlException` contains `STALE_VERSION` code, then it's a
        // specific `StaleVersionException`.
        return StaleVersionException(result.exception!.graphqlErrors);
      } else if (result.exception!.graphqlErrors.firstWhereOrNull(
            (e) =>
                e.extensions?['code'] == 'SESSION_EXPIRED' ||
                e.extensions?['code'] == 'AUTHENTICATION_REQUIRED' ||
                e.extensions?['code'] == 'AUTHENTICATION_FAILED',
          ) !=
          null) {
        return const AuthorizationException();
      } else if (result.exception!.graphqlErrors.any(
        (e) => e.message.contains('Expected input scalar `UserPhone`'),
      )) {
        return const InvalidScalarException<UserPhone>();
      }

      return GraphQlException(result.exception!.graphqlErrors);
    }

    if (result.exception!.linkException! is ServerException) {
      ServerException e = result.exception!.linkException! as ServerException;

      // If the original exception is "Failed to parse header value", then
      // it's `AuthorizationException`.
      if (e.originalException.toString() == 'Failed to parse header value') {
        return const AuthorizationException();
      }

      // If it's `SocketException` or "XMLHttpRequest error." then it's
      // `ConnectionException`.
      if (e.originalException is SocketException ||
          e.originalException.toString() == 'XMLHttpRequest error.') {
        return ConnectionException(e.originalException);
      }

      // If there are `errors`, then it's a backend unspecified error.
      // It might be an internal error, bad request or request error.
      if (e.parsedResponse?.errors != null) {
        var found = e.parsedResponse!.errors!.firstWhereOrNull(
          (v) => v.extensions != null && (v.extensions!['status'] == 401),
        );
        if (found != null) throw const AuthorizationException();
        return GraphQlException(e.parsedResponse!.errors!);
      }

      // If any `data` is available, then try to handle the exception as it
      // may be the specified backend error.
      if (e.parsedResponse?.data != null) {
        if (handleException != null) {
          return handleException(e.parsedResponse!.data!);
        }
      }
    }

    // If nothing was triggered, then re-throw the original exception.
    return result.exception!.linkException!.originalException;
  }

  return null;
}