bugwatch 0.1.1
bugwatch: ^0.1.1 copied to clipboard
BugWatch — crash, error, and log observability for Flutter. Capture exceptions, messages, breadcrumbs, and scope from your app via native iOS/Android bridges.
bugwatch #
BugWatch — crash, error, and log observability for Flutter. Capture exceptions, log messages, breadcrumbs, and user/scope context from your Flutter app and ship them to newinstance.cloud.
The Dart BugWatch API forwards each call across a method-channel bridge to the
native BugWatch iOS / Android SDKs, which own delivery, crash handling, device
collection, and session tracking.
Requirements #
- Flutter 3.3+
- iOS 14.0+
- Android API 24+, JDK 17
Quick start #
import 'package:bugwatch/bugwatch.dart';
await BugWatch.instance.init(const BugWatchOptions(
projectId: 'bwp_<your-project-id>',
appSecret: '<your-project-app-secret>',
environment: 'production',
release: '1.4.2+318',
// endpoint: 'https://api.newinstance.cloud', // default
));
appSecretis your project's signing secret. The native SDK uses it only to sign a short-lived ingest token locally (HMAC-SHA256) — the secret is never transmitted.
Capturing events #
// A handled error:
try {
await doRiskyThing();
} catch (error, stack) {
await BugWatch.instance.captureException(error, stack);
}
// A freeform log message:
await BugWatch.instance.captureMessage('Checkout started', level: Severity.info);
Severity is the platform-wide scale: trace (10), debug (20), info (30),
warn (40), error (50), fatal (60).
Scope #
Scope is attached to every subsequent event.
await BugWatch.instance.setUser(const BugWatchUser(
id: 'u_123',
email: 'ada@example.com',
username: 'ada',
));
await BugWatch.instance.setTag('screen', 'checkout');
await BugWatch.instance.setContext('cart_id', 'c_987');
await BugWatch.instance.setRelease('1.4.3+319');
await BugWatch.instance.addBreadcrumb(Breadcrumb(
category: 'navigation',
message: 'Opened checkout',
level: Severity.info,
));
Lifecycle #
await BugWatch.instance.flush(); // drain pending events
await BugWatch.instance.close(); // tear down
How captureException maps to native #
The Dart captureException(error, stack) passes the Dart runtime type, the
message, and a stringified Dart stack across the channel — there is no
JVM Throwable / Swift Error on the native side. To preserve the Dart type and
message, the native plugins capture an error-level message of the form
"<type>: <value>" (e.g. "StateError: Bad state: …") via the SDK's
captureMessage(…, level: error).
Fidelity limitation: the Dart stack string is not rendered as a native
stack trace, and the event is delivered as an error log rather than a native
exception object. (Synthesizing a RuntimeException / NSError would instead
report the native type — java.lang.RuntimeException / NSError — and lose
the Dart type, which is worse for grouping.) A Dart-stack-aware exception path is
a future enhancement.
Installation #
Android #
Autolink registers the plugin, which depends on the native BugWatch Android SDK
cloud.newinstance:bugwatch. It is resolved from mavenLocal() (added by the
plugin's android/build.gradle.kts); publish it from bug-watch-android with
./gradlew :sdk:publishToMavenLocal before building.
iOS #
CocoaPods autolink registers the plugin, which declares s.dependency 'BugWatch'
(the native BugWatch iOS SDK pod). Until that pod is published to a spec repo,
add a local path override to your app's Podfile:
pod 'BugWatch', :path => '../path/to/bug-watch-ios'
The host app's iOS deployment target must be 14.0+.
License #
MIT — see LICENSE.