Skip to content

Commit cc88179

Browse files
committed
chore: add bloc observer, set up zone guards
1 parent 32197d0 commit cc88179

File tree

2 files changed

+41
-20
lines changed

2 files changed

+41
-20
lines changed

lib/app_bloc_observer.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'dart:developer';
2+
import 'package:bloc/bloc.dart';
3+
4+
/// {@template app_bloc_observer}
5+
/// Custom instance of [BlocObserver] which logs
6+
/// any state changes and errors.
7+
/// {@endtemplate}
8+
class AppBlocObserver extends BlocObserver {
9+
/// {@macro app_bloc_observer}
10+
const AppBlocObserver();
11+
12+
@override
13+
void onChange(BlocBase<dynamic> bloc, Change<dynamic> change) {
14+
super.onChange(bloc, change);
15+
log('onChange(${bloc.runtimeType}, $change)');
16+
}
17+
18+
@override
19+
void onError(BlocBase<dynamic> bloc, Object error, StackTrace stackTrace) {
20+
log('onError(${bloc.runtimeType}, $error, $stackTrace)');
21+
super.onError(bloc, error, stackTrace);
22+
}
23+
}

lib/bootstrap.dart

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,30 @@ import 'dart:async';
22
import 'dart:developer';
33

44
import 'package:bloc/bloc.dart';
5+
import 'package:flutter/foundation.dart';
56
import 'package:flutter/widgets.dart';
7+
import 'package:sudoku/app_bloc_observer.dart';
68

7-
class AppBlocObserver extends BlocObserver {
8-
const AppBlocObserver();
9-
10-
@override
11-
void onChange(BlocBase<dynamic> bloc, Change<dynamic> change) {
12-
super.onChange(bloc, change);
13-
log('onChange(${bloc.runtimeType}, $change)');
14-
}
15-
16-
@override
17-
void onError(BlocBase<dynamic> bloc, Object error, StackTrace stackTrace) {
18-
log('onError(${bloc.runtimeType}, $error, $stackTrace)');
19-
super.onError(bloc, error, stackTrace);
20-
}
21-
}
22-
9+
/// Bootstrap is responsible for any common setup and calls
10+
/// [runApp] with the widget returned by [builder] in an error zone.
2311
Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
12+
// Log all uncaught build phase errors from the framework
2413
FlutterError.onError = (details) {
2514
log(details.exceptionAsString(), stackTrace: details.stack);
2615
};
2716

28-
Bloc.observer = const AppBlocObserver();
29-
30-
// Add cross-flavor configuration here
17+
// Log all uncaught asynchronous errors that aren't handled
18+
// by the Flutter framework.
19+
PlatformDispatcher.instance.onError = (error, stack) {
20+
log(error.toString(), stackTrace: stack);
21+
return true;
22+
};
3123

32-
runApp(await builder());
24+
await runZonedGuarded(
25+
() async {
26+
Bloc.observer = const AppBlocObserver();
27+
runApp(await builder());
28+
},
29+
(error, stackTrace) => log(error.toString(), stackTrace: stackTrace),
30+
);
3331
}

0 commit comments

Comments
 (0)