gql_error_link 0.2.3-alpha+1659802148043 copy "gql_error_link: ^0.2.3-alpha+1659802148043" to clipboard
gql_error_link: ^0.2.3-alpha+1659802148043 copied to clipboard

outdated

GQL Link to handle execution errors and exceptions

MIT License PRs Welcome Watch on GitHub Star on GitHub Watch on GitHub Discord

GQL Link to handle execution errors and exceptions.

Usage #

An example using ErrorLink to act on auth exceptions.

Note that this example is very inefficient because it not only updates token on every request, it does so only after the request has failed first. A more feature complete example of an auth link can be found here.

import "package:gql/language.dart";
import "package:gql_error_link/gql_error_link.dart";
import "package:gql_exec/gql_exec.dart";
import "package:gql_link/gql_link.dart";

// Let's imagine we have some terminating [Link]
final terminatingLink = Link.function(
  (request, [forward]) async* {
    // It expects [AuthToken] to be present in the context.
    final token = request.context.entry<AuthToken>();

    // If token is not present, it throws [AuthException].
    if (token == null) {
      throw AuthException();
    }

    // Otherwise, yield some [Response].
    yield Response(
      data: <String, String>{
        "magic": token.token,
      },
    );
  },
);

// In this case [AuthToken] is a simple container of a [String] token.
class AuthToken extends ContextEntry {
  final String token;

  const AuthToken({this.token});

  @override
  List<Object> get fieldsForEquality => [];
}

// Our terminating link defines it's own [AuthException]
class AuthException extends ServerException {}

// We have some means of getting a new valid token
Future<String> getNewToken() => Future.delayed(
      Duration(milliseconds: 10),
      () => "Valid token",
    );

// We'll want to handle [LinkException]s
Stream<Response> handleException(
  Request request,
  NextLink forward,
  LinkException exception,
) async* {
  // If the exception is [AuthException]
  if (exception is AuthException) {
    // We fetch a new token
    final token = await getNewToken();

    // Update the request with the new token
    final updatedRequest = request.withContextEntry(
      AuthToken(token: token),
    );

    // And try the request again
    yield* forward(updatedRequest);

    return;
  }

  // Otherwise, we rethrow the previous exception
  throw exception;
}

void main() async {
  // We use the [ErrorLink] by prepending it before the terminating link
  final link = Link.from([
    ErrorLink(onException: handleException),
    terminatingLink,
  ]);

  try {
    // Let's fetch the first Response
    final response = await link
        .request(
          Request(
            operation: Operation(
              document: parseString("{}"),
            ),
          ),
        )
        .first;

    // Internally the first response was an exception, but [ErrorLink] caught
    // it and retried the request with a valid token
    print(response.data);
  } catch (e) {
    // This was not even called
    print(e);
  }
}

Features and bugs #

Please file feature requests and bugs at the GitHub.

0
likes
0
points
43.7k
downloads

Publisher

verified publishergql-dart.dev

Weekly Downloads

GQL Link to handle execution errors and exceptions

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

async, gql_exec, gql_link, meta

More

Packages that depend on gql_error_link