3

I have a flutter application that uses graphql: ^5.0.0 to perform mutations and queries on my database and I'm trying to handle invalid token exceptions I get. When I get an invalid token error from my server, an error is thrown here.

error being thrown here

Here is the error making its way up into my code

here is the throw in my code

here is my code:

    try {
      final QueryResult result = await client.query(options);
      List<dynamic> taskList = result.data!['userTasksConnections']['tasks'];
      List<Task> tasks = [];
      for(int i = 0; i < taskList.length; i++) {
        tasks.add(Task.fromJson(taskList[i]));
      }
      return tasks;

    } on HttpLinkServerException catch(e) {
      if(e.parsedResponse?.errors?[0] == 'Invalid Token'){
        await UserRepo().getAccessToken();
        return getTasks(page: page, keyword: keyword);
      }
      else{
        return [];
      }
    }

since the error is clearly of type HttpLinkServerException I have an on HttpLinkServerException catch(). However, when the code runs the exception is not caught in the catch block and the code continues after the result await as if nothing happened, causing a null data exception on this line

      List<dynamic> taskList = result.data!['userTasksConnections']['tasks'];
Gwhyyy
  • 7,554
  • 3
  • 8
  • 35
Dean Packard
  • 238
  • 3
  • 11

1 Answers1

0

You need to write your own parser to fix this issue. You do so with something like this

import 'package:graphql/client.dart';

class CustomResponseParser extends ResponseParser {
  @override
  Response parseResponse(Map<String, dynamic> body) {
    Map<String, String> errors = new Map();
    if(body["errors"] != null) {
      errors['message'] = body["errors"][0];
    }
    Response res =  Response(
      errors: (body["errors"] as List?)
          ?.map(
            (dynamic error) => parseError(errors),
          )
          .toList(),
      data: body["data"] as Map<String, dynamic>?,
      context: Context().withEntry(
        ResponseExtensions(
          body["extensions"],
        ),
      ),
    );
    return res;
  }

  @override
  GraphQLError parseError(Map<String, dynamic> error) {
    return GraphQLError(
      message: error['message'],
    );
  }

}

And then you use it when initializing your graphqlClient like this

  final GraphQLClient client = GraphQLClient(
    cache: GraphQLCache(),
    link: AuthLink(getToken: () {
          if (store.state.auth.accessToken == '') {
            return "";
          } else {
            return "Bearer ${store.state.auth.accessToken}";
          }
        }).concat(
          HttpLink(
            Environment().config.apiHost,
            parser: CustomResponseParser()  
          )
        )
  );
Dean Packard
  • 238
  • 3
  • 11