Skip to content

Commit

Permalink
Merge pull request #183 from bugsnag/releases/v2.4.0
Browse files Browse the repository at this point in the history
v2.4.0
  • Loading branch information
lemnik authored Dec 1, 2022
2 parents ab1b9cc + e47a2d3 commit 8d756ed
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 38 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 2.4.0 (2022-12-01)

- Added `maxStringValueLength` option to `bugsnag.start` to allow truncation behaviour to be configured.
[#179](https://github.com/bugsnag/bugsnag-flutter/pull/179)
- Native-first hot-reloads (using `bugnag.attach`) will no longer cause errors, but will instead emit a warning
[#182](https://github.com/bugsnag/bugsnag-flutter/pull/182)
- Update bugsnag-android from v5.28.1 to [v5.28.3](https://github.com/bugsnag/bugsnag-android/blob/master/CHANGELOG.md#5283-2022-11-16)

## 2.3.0 (2022-10-27)

- Added `BugsnagTelemetryType.usage` to allow sending of usage telemetry to be disabled.
Expand Down
36 changes: 36 additions & 0 deletions features/attach_flutter.feature
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,39 @@ Feature: Attach to running native Bugsnag instance
When I configure the app to run in the "disableDartErrors" state
And I run "AttachBugsnagScenario"
Then I should receive no errors

Scenario: multiple attaches with a handled exception
When I configure the app to run in the "handled extra-attach" state
And I run "AttachBugsnagScenario"
Then I wait to receive 2 errors
And the error is valid for the error reporting API version "4.0" for the "Flutter Bugsnag Notifier" notifier
And the exception "errorClass" equals "_Exception"
And the exception "message" equals "Handled exception with attached info"
And the error payload field "events.0.unhandled" is false
And the error payload field "events.0.threads" is a non-empty array
And the event "severity" equals "warning"

And the event "user.id" equals "test-user-id"
And the event "user.email" is null
And the event "user.name" equals "Old Man Tables"

And the event "context" equals "flutter-test-context"
And event 0 contains the feature flag "demo-mode" with no variant
And event 0 contains the feature flag "sample-group" with variant "123"

Scenario: multiple attaches with an unhandled exception
When I configure the app to run in the "extra-attach" state
When I run "AttachBugsnagScenario"
Then I wait to receive 2 errors
And the error is valid for the error reporting API version "4.0" for the "Flutter Bugsnag Notifier" notifier
And the exception "errorClass" equals "_Exception"
And the exception "message" equals "Unhandled exception with attached info"
And the error payload field "events.0.threads" is a non-empty array
And the event "context" equals "flutter-test-context"
And the event "severity" equals "error"
And the event "unhandled" is true
And the event "user.email" is null
And the event "user.id" equals "test-user-id"
And the event "user.name" equals "Old Man Tables"
And event 0 contains the feature flag "demo-mode" with no variant
And event 0 contains the feature flag "sample-group" with variant "123"
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ class AttachBugsnagScenario extends Scenario {
@override
Future<void> run() async {
await startNativeNotifier();

final attachFuture = await doAttach();
if (extraConfig?.contains("extra-attach") == true) {
await doAttach();
}
}

Future<void> doAttach() async {
await bugsnag.attach(
runApp: () async {
await Future.wait([
Expand Down
2 changes: 1 addition & 1 deletion packages/bugsnag_breadcrumbs_dart_io/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: bugsnag_breadcrumbs_dart_io
description: Bugsnag network breadcrumbs for dart:io's HttpClient
version: 2.3.0
version: 2.4.0
homepage: https://www.bugsnag.com/
documentation: https://docs.bugsnag.com/platforms/flutter/
repository: https://github.com/bugsnag/bugsnag-flutter
Expand Down
2 changes: 1 addition & 1 deletion packages/bugsnag_breadcrumbs_http/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: bugsnag_breadcrumbs_http
description: Bugsnag network breadcrumbs for https://pub.dev/packages/http
version: 2.3.0
version: 2.4.0
homepage: https://www.bugsnag.com/
documentation: https://docs.bugsnag.com/platforms/flutter/
repository: https://github.com/bugsnag/bugsnag-flutter
Expand Down
2 changes: 1 addition & 1 deletion packages/bugsnag_flutter/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ android {
}

dependencies {
implementation 'com.bugsnag:bugsnag-android:5.28.1'
implementation 'com.bugsnag:bugsnag-android:5.28.3'
testImplementation 'junit:junit:4.12'
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ class BugsnagFlutter {

private InternalHooks client;

private static boolean isAnyAttached = false;
private boolean isAttached = false;
private static boolean isAttached = false;

private static boolean isAnyStarted = false;
private boolean isStarted = false;
Expand All @@ -53,19 +52,15 @@ class BugsnagFlutter {
Context context;

JSONObject attach(@NonNull JSONObject args) throws Exception {
if (isAttached) {
throw new IllegalStateException("bugsnag.attach() may not be called more than once");
}

JSONObject result = new JSONObject()
.put("config", new JSONObject()
.put("enabledErrorTypes", new JSONObject()
.put("dartErrors", BugsnagFlutterConfiguration.enabledErrorTypes.dartErrors)
)
);

if (isAnyAttached) {
Log.i("BugsnagFlutter", "bugsnag.attach() was called from a previous Flutter context. Ignoring.");
if (isAttached) {
Log.i("BugsnagFlutter", "bugsnag.attach() has already been called. Ignoring.");
return result;
}

Expand All @@ -83,7 +78,6 @@ JSONObject attach(@NonNull JSONObject args) throws Exception {
notifier.setUrl(notifierJson.getString("url"));
notifier.setDependencies(Collections.singletonList(new Notifier()));

isAnyAttached = true;
isAttached = true;
return result;
}
Expand Down Expand Up @@ -117,6 +111,7 @@ Void start(@NonNull JSONObject args) throws Exception {
configuration.setMaxBreadcrumbs(args.optInt("maxBreadcrumbs", configuration.getMaxBreadcrumbs()));
configuration.setMaxPersistedEvents(args.optInt("maxPersistedEvents", configuration.getMaxPersistedEvents()));
configuration.setMaxPersistedSessions(args.optInt("maxPersistedSessions", configuration.getMaxPersistedSessions()));
configuration.setMaxStringValueLength(args.optInt("maxStringValueLength", configuration.getMaxStringValueLength()));
configuration.setReleaseStage(args.optString("releaseStage", configuration.getReleaseStage()));
configuration.setPersistUser(args.optBoolean("persistUser", configuration.getPersistUser()));

Expand Down
51 changes: 27 additions & 24 deletions packages/bugsnag_flutter/ios/Classes/BugsnagFlutterPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
#import <mach-o/dyld.h>
#import <objc/runtime.h>

// Constructs a key path, with a compile-time check in DEBUG builds.
// https://pspdfkit.com/blog/2017/even-swiftier-objective-c/#checked-keypaths
#if defined(DEBUG) && DEBUG
#define BSG_KEYPATH(object, property) ((void)(NO && ((void)object.property, NO)), @ #property)
#else
#define BSG_KEYPATH(object, property) @ #property
#endif

// Will be nil in debug builds because they not contain any Dart code (App.framework)
static NSString *DartCodeBuildId;

Expand Down Expand Up @@ -59,7 +67,6 @@ @interface BugsnagStackframe (BugsnagFlutterPlugin)

@interface BugsnagFlutterPlugin ()

@property (nonatomic, getter=isAttached) BOOL attached;
@property (nonatomic, getter=isStarted) BOOL started;
@property (nullable, nonatomic) NSArray *projectPackages;

Expand Down Expand Up @@ -199,10 +206,6 @@ - (NSDictionary *)getMetadata:(NSDictionary *)arguments {
}

- (NSDictionary *)attach:(NSDictionary *)arguments {
if (self.isAttached) {
[NSException raise:NSInternalInconsistencyException format:@"bugsnag.attach() may not be called more than once"];
}

NSDictionary *result = @{
@"config": @{
@"enabledErrorTypes": @{
Expand All @@ -211,9 +214,9 @@ - (NSDictionary *)attach:(NSDictionary *)arguments {
}
};

static BOOL isAnyAttached;
if (isAnyAttached) {
NSLog(@"bugsnag.attach() was called from a previous Flutter context. Ignoring.");
static BOOL isAttached;
if (isAttached) {
NSLog(@"bugsnag.attach() has already been called. Ignoring.");
return result;
}

Expand All @@ -230,8 +233,7 @@ - (NSDictionary *)attach:(NSDictionary *)arguments {

self.projectPackages = BugsnagFlutterConfiguration.projectPackages;

isAnyAttached = YES;
self.attached = YES;
isAttached = YES;
return result;
}

Expand All @@ -253,20 +255,21 @@ - (void)start:(NSDictionary *)arguments {

BugsnagConfiguration *configuration = [BugsnagConfiguration loadConfig];

for (NSString *key in @[@"apiKey",
@"appHangThresholdMillis",
@"appType",
@"appVersion",
@"autoDetectErrors",
@"autoTrackSessions",
@"bundleVersion",
@"context",
@"launchDurationMillis",
@"maxBreadcrumbs",
@"maxPersistedEvents",
@"maxPersistedSessions",
@"releaseStage",
@"sendLaunchCrashesSynchronously"]) {
for (NSString *key in @[BSG_KEYPATH(configuration, apiKey),
BSG_KEYPATH(configuration, appHangThresholdMillis),
BSG_KEYPATH(configuration, appType),
BSG_KEYPATH(configuration, appVersion),
BSG_KEYPATH(configuration, autoDetectErrors),
BSG_KEYPATH(configuration, autoTrackSessions),
BSG_KEYPATH(configuration, bundleVersion),
BSG_KEYPATH(configuration, context),
BSG_KEYPATH(configuration, launchDurationMillis),
BSG_KEYPATH(configuration, maxBreadcrumbs),
BSG_KEYPATH(configuration, maxPersistedEvents),
BSG_KEYPATH(configuration, maxPersistedSessions),
BSG_KEYPATH(configuration, maxStringValueLength),
BSG_KEYPATH(configuration, releaseStage),
BSG_KEYPATH(configuration, sendLaunchCrashesSynchronously)]) {
id value = arguments[key];
if (value && value != [NSNull null]) {
[configuration setValue:value forKey:key];
Expand Down
4 changes: 3 additions & 1 deletion packages/bugsnag_flutter/lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import 'model.dart';
final _notifier = {
'name': 'Flutter Bugsnag Notifier',
'url': 'https://github.com/bugsnag/bugsnag-flutter',
'version': '2.3.0'
'version': '2.4.0'
};

abstract class BugsnagClient {
Expand Down Expand Up @@ -669,6 +669,7 @@ class Bugsnag extends BugsnagClient with DelegateClient {
int maxBreadcrumbs = 50,
int maxPersistedSessions = 128,
int maxPersistedEvents = 32,
int maxStringValueLength = 10000,
bool autoTrackSessions = true,
bool autoDetectErrors = true,
BugsnagThreadSendPolicy sendThreads = BugsnagThreadSendPolicy.always,
Expand Down Expand Up @@ -716,6 +717,7 @@ class Bugsnag extends BugsnagClient with DelegateClient {
'maxBreadcrumbs': maxBreadcrumbs,
'maxPersistedSessions': maxPersistedSessions,
'maxPersistedEvents': maxPersistedEvents,
'maxStringValueLength': maxStringValueLength,
'autoTrackSessions': autoTrackSessions,
'autoDetectErrors': autoDetectErrors,
'sendThreads': sendThreads.toName(),
Expand Down
2 changes: 1 addition & 1 deletion packages/bugsnag_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: bugsnag_flutter
description: Bugsnag crash monitoring and reporting tool for Flutter apps
version: 2.3.0
version: 2.4.0
homepage: https://www.bugsnag.com/
documentation: https://docs.bugsnag.com/platforms/flutter/
repository: https://github.com/bugsnag/bugsnag-flutter
Expand Down

0 comments on commit 8d756ed

Please sign in to comment.