Skip to content

Commit

Permalink
Merge pull request #110 from rollbar/native_hook
Browse files Browse the repository at this point in the history
Initialize the native Rollbar/Android SDK as a hook instead of explicitly
  • Loading branch information
matux authored Aug 2, 2023
2 parents 6198568 + 4167926 commit 5e5823a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 24 deletions.
19 changes: 19 additions & 0 deletions rollbar_flutter/lib/src/hooks/native_hook.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:flutter/services.dart';
import 'package:rollbar_dart/rollbar.dart';

import '../method_channel.dart';
import 'hook.dart';

class NativeHook implements Hook {
static const _platform = MethodChannel('com.rollbar.flutter');

@override
Future<void> install(final Config config) async {
await _platform.initialize(config: config);
}

@override
Future<void> uninstall() async {
await _platform.close();
}
}
9 changes: 9 additions & 0 deletions rollbar_flutter/lib/src/hooks/platform_hook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ class PlatformHook implements Hook {
ErrorCallback? _originalOnError;
PlatformDispatcher? _platformDispatcher;

static bool get isAvailable {
try {
(PlatformDispatcher.instance as dynamic)?.onError;
return true;
} on NoSuchMethodError {
return false;
}
}

bool onError(Object exception, StackTrace stackTrace) {
Rollbar.error(exception, stackTrace);

Expand Down
18 changes: 18 additions & 0 deletions rollbar_flutter/lib/src/method_channel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:flutter/services.dart';
import 'package:rollbar_flutter/rollbar_flutter.dart';

extension RollbarMethodChannel on MethodChannel {
/// The platform-specific path where we can persist data if needed.
Future<String> get persistencePath async =>
await invokeMethod('persistencePath');

/// Initializes the native Apple/Android SDK Rollbar notifier
/// using the given configuration.
Future<void> initialize({required Config config}) async =>
await invokeMethod('initialize', config.toMap());

/// Unwinds the native Apple/Android SDK Rollbar notifier.
///
/// This is a no-op at the moment.
Future<void> close() async => await invokeMethod('close');
}
37 changes: 13 additions & 24 deletions rollbar_flutter/lib/src/rollbar.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
Expand All @@ -10,16 +9,9 @@ import 'package:rollbar_dart/rollbar.dart';
import 'hooks/hook.dart';
import 'hooks/flutter_hook.dart';
import 'hooks/platform_hook.dart';
import 'hooks/native_hook.dart';
import 'platform_transformer.dart';

extension _Methods on MethodChannel {
Future<void> initialize({required Config config}) async =>
await invokeMethod('initialize', config.toMap());

/// The platform-specific path where we can persist data if needed.
Future<String> get persistencePath async =>
await invokeMethod('persistencePath');
}
import 'method_channel.dart';

typedef RollbarClosure = FutureOr<void> Function();

Expand All @@ -35,13 +27,20 @@ class RollbarFlutter {
RollbarClosure appRunner,
) async {
if (!config.handleUncaughtErrors) {
await _run(config, appRunner);
} else if (requiresCustomZone) {
await _run(config, appRunner, [NativeHook()]);
} else if (!PlatformHook.isAvailable) {
await runZonedGuarded(
() async => await _run(config, appRunner, [FlutterHook()]),
() async => await _run(config, appRunner, [
FlutterHook(),
NativeHook(),
]),
Rollbar.error);
} else {
await _run(config, appRunner, [FlutterHook(), PlatformHook()]);
await _run(config, appRunner, [
FlutterHook(),
PlatformHook(),
NativeHook(),
]);
}
}

Expand All @@ -62,16 +61,6 @@ class RollbarFlutter {
await hook.install(config);
}

await _platform.initialize(config: config);
await appRunner();
}

static bool get requiresCustomZone {
try {
(PlatformDispatcher.instance as dynamic)?.onError;
return false;
} on NoSuchMethodError {
return true;
}
}
}

0 comments on commit 5e5823a

Please sign in to comment.