1
1
import 'dart:async' ;
2
2
3
+ import 'default_integrations.dart' ;
3
4
import 'hub.dart' ;
4
5
import 'hub_adapter.dart' ;
5
6
import 'noop_hub.dart' ;
7
+ import 'noop_isolate_error_integration.dart'
8
+ if (dart.library.io) 'isolate_error_integration.dart' ;
6
9
import 'protocol.dart' ;
7
10
import 'sentry_client.dart' ;
8
11
import 'sentry_options.dart' ;
12
+ import 'utils.dart' ;
9
13
10
14
/// Configuration options callback
11
15
typedef OptionsConfiguration = FutureOr <void > Function (SentryOptions );
12
16
17
+ /// Runs a callback inside of the `runZonedGuarded` method, useful for running your `runApp(MyApp())`
18
+ typedef AppRunner = FutureOr <void > Function ();
19
+
13
20
/// Sentry SDK main entry point
14
21
class Sentry {
15
22
static Hub _hub = NoOpHub ();
@@ -20,11 +27,20 @@ class Sentry {
20
27
static Hub get currentHub => _hub;
21
28
22
29
/// Initializes the SDK
23
- static Future <void > init (OptionsConfiguration optionsConfiguration) async {
30
+ /// passing a [AppRunner] callback allows to run the app within its own error zone (`runZonedGuarded` )
31
+ /// https://api.dart.dev/stable/2.10.4/dart-async/runZonedGuarded.html
32
+ static Future <void > init (
33
+ OptionsConfiguration optionsConfiguration, [
34
+ AppRunner appRunner,
35
+ List <Integration > initialIntegrations,
36
+ ]) async {
24
37
if (optionsConfiguration == null ) {
25
38
throw ArgumentError ('OptionsConfiguration is required.' );
26
39
}
40
+
27
41
final options = SentryOptions ();
42
+ await _initDefaultValues (options, appRunner, initialIntegrations);
43
+
28
44
await optionsConfiguration (options);
29
45
30
46
if (options == null ) {
@@ -34,6 +50,47 @@ class Sentry {
34
50
await _init (options);
35
51
}
36
52
53
+ static Future <void > _initDefaultValues (
54
+ SentryOptions options,
55
+ AppRunner appRunner,
56
+ List <Integration > initialIntegrations,
57
+ ) async {
58
+ // if no environment is set, we set 'production' by default, but if we know it's
59
+ // a non-release build, or the SENTRY_ENVIRONMENT is set, we read from it.
60
+ if (const bool .hasEnvironment ('SENTRY_ENVIRONMENT' ) || ! isReleaseMode) {
61
+ options.environment = const String .fromEnvironment (
62
+ 'SENTRY_ENVIRONMENT' ,
63
+ defaultValue: 'debug' ,
64
+ );
65
+ }
66
+
67
+ // if the SENTRY_DSN is set, we read from it.
68
+ options.dsn = const bool .hasEnvironment ('SENTRY_DSN' )
69
+ ? const String .fromEnvironment ('SENTRY_DSN' )
70
+ : options.dsn;
71
+
72
+ // we need to execute integrations in a specific order sometimes,
73
+ // and this initialIntegrations list makes it possible to inject and add
74
+ // integrations before the runZonedGuardedIntegration gets added
75
+ if (initialIntegrations != null && initialIntegrations.isNotEmpty) {
76
+ initialIntegrations
77
+ .forEach ((integration) => options.addIntegration (integration));
78
+ }
79
+
80
+ // Throws when running on the browser
81
+ if (! isWeb) {
82
+ // catch any errors that may occur within the entry function, main()
83
+ // in the ‘root zone’ where all Dart programs start
84
+ options.addIntegration (isolateErrorIntegration);
85
+ }
86
+
87
+ // finally the runZonedGuarded, catch any errors in Dart code running
88
+ // ‘outside’ the Flutter framework
89
+ if (appRunner != null ) {
90
+ options.addIntegration (runZonedGuardedIntegration (appRunner));
91
+ }
92
+ }
93
+
37
94
/// Initializes the SDK
38
95
static Future <void > _init (SentryOptions options) async {
39
96
if (isEnabled) {
0 commit comments