debugCheckZone method

bool debugCheckZone(
  1. String entryPoint
)

Checks that the current Zone is the same as that which was used to initialize the binding.

If the current zone (Zone.current) is not the zone that was active when the binding was initialized, then this method generates a FlutterError exception with detailed information. The exception is either thrown directly, or reported via FlutterError.reportError, depending on the value of BindingBase.debugZoneErrorsAreFatal.

To silence the message displayed by debugCheckZone, ensure that the same zone is used when calling ensureInitialized() as when calling the framework in any other context (e.g. via runApp). For example, consider keeping a reference to the zone used to initialize the binding, and using Zone.run to use it again when calling into the framework.

Usage

The binding is considered initialized once BindingBase.initInstances has run; if this is called before then, it will throw an AssertionError.

The entryPoint parameter is the name of the API that is checking the zones are consistent, for example, 'runApp'.

This function always returns true (if it does not throw). It is expected to be invoked via the binding instance, e.g.:

void startup() {
  WidgetsBinding binding = WidgetsFlutterBinding.ensureInitialized();
  assert(binding.debugCheckZone('startup'));
  // ...
}

If the binding expects to be used with multiple zones, it should override this method to return true always without throwing. (For example, the bindings used with flutter_test do this as they make heavy use of zones to drive the framework with an artificial clock and to catch errors and report them as test failures.)

Implementation

bool debugCheckZone(String entryPoint) {
  assert(() {
    assert(_debugBindingZone != null, 'debugCheckZone can only be used after the binding is fully initialized.');
    if (Zone.current != _debugBindingZone) {
      final Error message = FlutterError(
        'Zone mismatch.\n'
        'The Flutter bindings were initialized in a different zone than is now being used. '
        'This will likely cause confusion and bugs as any zone-specific configuration will '
        'inconsistently use the configuration of the original binding initialization zone '
        'or this zone based on hard-to-predict factors such as which zone was active when '
        'a particular callback was set.\n'
        'It is important to use the same zone when calling `ensureInitialized` on the binding '
        'as when calling `$entryPoint` later.\n'
        'To make this ${ debugZoneErrorsAreFatal ? 'error non-fatal' : 'warning fatal' }, '
        'set BindingBase.debugZoneErrorsAreFatal to ${!debugZoneErrorsAreFatal} before the '
        'bindings are initialized (i.e. as the first statement in `void main() { }`).',
      );
      if (debugZoneErrorsAreFatal) {
        throw message;
      }
      FlutterError.reportError(FlutterErrorDetails(
        exception: message,
        stack: StackTrace.current,
        context: ErrorDescription('during $entryPoint'),
      ));
    }
    return true;
  }());
  return true;
}