Future<Null> guard(Future<Null> body())

Calls the given callback in a new async scope. The callback argument is the asynchronous body of the calling method. The calling method is said to be "guarded". Nested calls to guarded methods from within the body of this one are fine, but calls to other guarded methods from outside the body of this one before this one has finished will throw an exception.

This method first calls guardSync.

Source

static Future<Null> guard(Future<Null> body()) {
  guardSync();
  Zone zone = Zone.current.fork(
    zoneValues: <dynamic, dynamic>{
      _scopeStack: true // so we can recognize this as our own zone
    }
  );
  _AsyncScope scope = new _AsyncScope(StackTrace.current, zone);
  _scopeStack.add(scope);
  Future<Null> result = scope.zone.run(body);
  void completionHandler(dynamic error, StackTrace stack) {
    assert(_scopeStack.isNotEmpty);
    assert(_scopeStack.contains(scope));
    bool leaked = false;
    _AsyncScope closedScope;
    StringBuffer message = new StringBuffer();
    while (_scopeStack.isNotEmpty) {
      closedScope = _scopeStack.removeLast();
      if (closedScope == scope)
        break;
      if (!leaked) {
        message.writeln('Asynchronous call to guarded function leaked. You must use "await" with all Future-returning test APIs.');
        leaked = true;
      }
      final _StackEntry originalGuarder = _findResponsibleMethod(closedScope.creationStack, 'guard', message);
      if (originalGuarder != null) {
        message.writeln(
          'The test API method "${originalGuarder.methodName}" '
          'from class ${originalGuarder.className} '
          'was called from ${originalGuarder.callerFile} '
          'on line ${originalGuarder.callerLine}, '
          'but never completed before its parent scope closed.'
        );
      }
    }
    if (leaked) {
      if (error != null) {
        message.writeln('An uncaught exception may have caused the guarded function leak. The exception was:');
        message.writeln('$error');
        message.writeln('The stack trace associated with this exception was:');
        FlutterError.defaultStackFilter(stack.toString().trimRight().split('\n')).forEach(message.writeln);
      }
      throw new FlutterError(message.toString().trimRight());
    }
  }
  return result.then(
    (Null value) => completionHandler(null, null),
    onError: completionHandler
  );
}