Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added a mutable Bugsnag.context property #466

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ Bugsnag Notifiers on other platforms.
`BugsnagConfiguration` value but can be overridden in event passed to the
`Bugsnag.notify()` callback.
[#458](https://github.com/bugsnag/bugsnag-cocoa/pull/458)

* Added `Bugsnag.context`, replicating the `BugsnagConfiguration` property. This is
mutable and may be changed at any point. Changes are propagated to the `BugsnagConfiguration`
property.
[#466](https://github.com/bugsnag/bugsnag-cocoa/pull/466)

* `Bugsnag.stopSession()` is now `Bugsnag.pauseSession()`. This renaming has
also been applied to the `BugsnagNotifier` and `BugsnagSessionTracker` classes.
Expand Down
8 changes: 8 additions & 0 deletions Source/Bugsnag.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,12 @@ static NSString *_Nonnull const BugsnagSeverityInfo = @"info";
+ (void)setBreadcrumbCapacity:(NSUInteger)capacity
__deprecated_msg("Use [BugsnagConfiguration setMaxBreadcrumbs:] instead");


/**
* Replicates BugsnagConfiguration.context
*
* @param context A general summary of what was happening in the application
*/
+ (void)setContext:(NSString *_Nullable)context;

@end
4 changes: 4 additions & 0 deletions Source/Bugsnag.m
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ + (id _Nullable )getMetadata:(NSString *_Nonnull)section
return [[[self configuration] metadata] getMetadata:section key:key];
}

+ (void)setContext:(NSString *_Nullable)context {
[self configuration].context = context;
}

@end

//
Expand Down
12 changes: 11 additions & 1 deletion Source/BugsnagEvent.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ id BSGLoadConfigValue(NSDictionary *report, NSString *valueName) {
?: [report valueForKeyPath:fallbackKeypath]; // some custom values are nested
}

/**
* Attempt to find a context (within which the event is being reported)
* This can be found in user-set metadata of varying specificity or the global
* configuration. Returns nil if no context can be found.
*
* @param report A dictionary of report data
* @param metadata Additional relevant data
* @returns A string context if found, or nil
*/
NSString *BSGParseContext(NSDictionary *report, NSDictionary *metadata) {
id context = [report valueForKeyPath:@"user.overrides.context"];
if ([context isKindOfClass:[NSString class]])
Expand Down Expand Up @@ -333,7 +342,8 @@ - (instancetype)initWithKSReport:(NSDictionary *)report {
_metadata = metadata ?: [NSDictionary new];
_releaseStage = config.releaseStage;
_notifyReleaseStages = config.notifyReleaseStages;
_context = BSGParseContext(nil, metadata);
// Set context based on current values. May be nil.
_context = metadata[BSGKeyContext] ?: [[Bugsnag configuration] context];
_breadcrumbs = [config.breadcrumbs arrayValue];
_overrides = [NSDictionary new];

Expand Down
47 changes: 47 additions & 0 deletions Tests/BugsnagTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,51 @@ -(void)testBugsnagPauseSession {
[Bugsnag pauseSession];
}

/**
* Test that the BugsnagConfiguration-mirroring Bugsnag.context is mutable
*/
- (void)testMutableContext {
// Allow for checks inside blocks that may (potentially) be run asynchronously
__block XCTestExpectation *expectation1 = [self expectationWithDescription:@"Localized metadata changes"];

NSError *error;
BugsnagConfiguration *configuration = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1 error:&error];
[configuration setContext:@"firstContext"];
[configuration addBeforeSendBlock:^bool(NSDictionary * _Nonnull rawEventData,
BugsnagEvent * _Nonnull reports)
{
return false;
}];

[Bugsnag startBugsnagWithConfiguration:configuration];

NSException *exception1 = [[NSException alloc] initWithName:@"exception1" reason:@"reason1" userInfo:nil];

// Check that the context is set going in to the test and that we can change it
[Bugsnag notify:exception1 block:^(BugsnagEvent * _Nonnull event) {
XCTAssertEqual([[Bugsnag configuration] context], @"firstContext");

// Change the global context
[Bugsnag setContext:@"secondContext"];

// Check that it's made it into the configuration (from the point of view of the block)
// and that setting it here doesn't affect the event's value.
XCTAssertEqual([[Bugsnag configuration] context], @"secondContext");
XCTAssertEqual([event context], @"firstContext");

[expectation1 fulfill];
}];

// Test that the context (changed inside the notify block) remains changed
// And that the event picks up this value.
[self waitForExpectationsWithTimeout:5.0 handler:^(NSError * _Nullable error) {
XCTAssertEqual([[Bugsnag configuration] context], @"secondContext");

[Bugsnag notify:exception1 block:^(BugsnagEvent * _Nonnull report) {
XCTAssertEqual([[Bugsnag configuration] context], @"secondContext");
robinmacharg marked this conversation as resolved.
Show resolved Hide resolved
XCTAssertEqual([report context], @"secondContext");
}];
}];
}

@end