// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:async'; import 'package:flutter_tools/src/base/async_guard.dart'; import '../../src/common.dart'; Future<void> asyncError() { final Completer<void> completer = Completer<void>(); final Completer<void> errorCompleter = Completer<void>(); errorCompleter.completeError('Async Doom', StackTrace.current); return completer.future; } Future<void> syncError() { throw 'Sync Doom'; } Future<void> syncAndAsyncError() { final Completer<void> errorCompleter = Completer<void>(); errorCompleter.completeError('Async Doom', StackTrace.current); throw 'Sync Doom'; } void main() { Completer<void> caughtInZone; bool caughtByZone = false; bool caughtByHandler = false; Zone zone; setUp(() { caughtInZone = Completer<void>(); caughtByZone = false; caughtByHandler = false; zone = Zone.current.fork(specification: ZoneSpecification( handleUncaughtError: ( Zone self, ZoneDelegate parent, Zone zone, Object error, StackTrace stackTrace, ) { caughtByZone = true; if (!caughtInZone.isCompleted) { caughtInZone.complete(); } }, )); }); test('asyncError percolates through zone', () async { await zone.run(() async { try { // Completer is required or else we timeout. await Future.any(<Future<void>>[asyncError(), caughtInZone.future]); } on String { caughtByHandler = true; } }); expect(caughtByZone, true); expect(caughtByHandler, false); }); test('syncAndAsyncError percolates through zone', () async { await zone.run(() async { try { // Completer is required or else we timeout. await Future.any(<Future<void>>[syncAndAsyncError(), caughtInZone.future]); } on String { caughtByHandler = true; } }); expect(caughtByZone, true); expect(caughtByHandler, true); }); test('syncError percolates through zone', () async { await zone.run(() async { try { await syncError(); } on String { caughtByHandler = true; } }); expect(caughtByZone, false); expect(caughtByHandler, true); }); test('syncError is caught by asyncGuard', () async { await zone.run(() async { try { await asyncGuard(syncError); } on String { caughtByHandler = true; } }); expect(caughtByZone, false); expect(caughtByHandler, true); }); test('asyncError is caught by asyncGuard', () async { await zone.run(() async { try { await asyncGuard(asyncError); } on String { caughtByHandler = true; } }); expect(caughtByZone, false); expect(caughtByHandler, true); }); test('asyncAndSyncError is caught by asyncGuard', () async { await zone.run(() async { try { await asyncGuard(syncAndAsyncError); } on String { caughtByHandler = true; } }); expect(caughtByZone, false); expect(caughtByHandler, true); }); }