From 2f9a7cfd55972d72c8bc648ccb921af4da92a77a Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Wed, 25 Mar 2020 17:16:24 +0000 Subject: [PATCH 1/2] feat: remove unused APIs on BugsnagEvent interface --- CHANGELOG.md | 3 + Source/Bugsnag.m | 5 ++ Source/BugsnagClient.m | 5 ++ Source/BugsnagEvent.h | 83 ------------------- Source/BugsnagEvent.m | 69 +++++++-------- Source/BugsnagHandledState.h | 19 +++++ Source/BugsnagHandledState.m | 20 +++++ Source/BugsnagSink.m | 5 ++ Tests/BugsnagEventTests.m | 6 ++ UPGRADING.md | 18 ++++ features/cross_notifier_notify.feature | 26 +----- .../HandledErrorOverrideScenario.swift | 3 - .../HandledInternalNotifyScenario.swift | 1 - .../UnhandledInternalNotifyScenario.swift | 1 - features/handled_errors.feature | 2 - .../BugsnagEventFromKSCrashReportTest.m | 7 ++ 16 files changed, 125 insertions(+), 148 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ffb1e9b3..6f810c98d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Bugsnag Notifiers on other platforms. ## Enhancements +* Remove unused APIs on `BugsnagEvent` interface + [#498](https://github.com/bugsnag/bugsnag-cocoa/pull/498) + * Remove `leaveBreadcrumbWithBlock` from public api on `Bugsnag` [#491](https://github.com/bugsnag/bugsnag-cocoa/pull/491) diff --git a/Source/Bugsnag.m b/Source/Bugsnag.m index 6bb9b663a..888cde6a1 100644 --- a/Source/Bugsnag.m +++ b/Source/Bugsnag.m @@ -30,6 +30,7 @@ #import "BugsnagClient.h" #import "BugsnagKeys.h" #import "BugsnagPlugin.h" +#import "BugsnagHandledState.h" static BugsnagClient *bsg_g_bugsnag_client = NULL; @@ -42,6 +43,10 @@ @interface NSDictionary (BSGKSMerge) - (NSDictionary *)BSG_mergedInto:(NSDictionary *)dest; @end +@interface BugsnagEvent () +@property(readwrite) NSUInteger depth; +@end + @implementation Bugsnag + (void)startBugsnagWithApiKey:(NSString *)apiKey { diff --git a/Source/BugsnagClient.m b/Source/BugsnagClient.m index 84007b85e..abcd92907 100644 --- a/Source/BugsnagClient.m +++ b/Source/BugsnagClient.m @@ -215,6 +215,11 @@ @interface BugsnagConfiguration () @property(nonatomic, readwrite, strong) NSMutableSet *plugins; @end +@interface BugsnagEvent () +@property(readonly, copy, nonnull) NSDictionary *overrides; +@property(readwrite) NSUInteger depth; +@end + @implementation BugsnagClient @synthesize configuration; diff --git a/Source/BugsnagEvent.h b/Source/BugsnagEvent.h index 65ba2fa88..edd879a07 100644 --- a/Source/BugsnagEvent.h +++ b/Source/BugsnagEvent.h @@ -19,25 +19,6 @@ typedef NS_ENUM(NSUInteger, BSGSeverity) { BSGSeverityInfo, }; -/** - * Convert a string to a severity value - * - * @param severity Intended severity value, such as info, warning, or error - * - * @return converted severity level or BSGSeverityError if no conversion is - * found - */ -BSGSeverity BSGParseSeverity(NSString *_Nonnull severity); - -/** - * Serialize a severity for JSON payloads - * - * @param severity a severity - * - * @return the equivalent string value - */ -NSString *_Nonnull BSGFormatSeverity(BSGSeverity severity); - @interface BugsnagEvent : NSObject // ----------------------------------------------------------------------------- @@ -88,43 +69,6 @@ initWithErrorName:(NSString *_Nonnull)name handledState:(BugsnagHandledState *_Nonnull)handledState session:(BugsnagSession *_Nullable)session; -// ----------------------------------------------------------------------------- -// MARK: - Misc. Methods -// ----------------------------------------------------------------------------- - -/** - * Serialize a crash report as a JSON payload - * - * @param data top level report data, may need to be modified based on - * environment - * - * @return a crash report - */ -- (NSDictionary *_Nonnull)serializableValueWithTopLevelData: - (NSMutableDictionary *_Nonnull)data -__deprecated_msg("Use toJson: instead."); - -- (NSDictionary *_Nonnull)toJson; - -/** - * Whether this report should be sent, based on release stage information - * cached at crash time and within the application currently - * - * @return YES if the report should be sent - */ -- (BOOL)shouldBeSent; - -/** - * Prepend a custom stacktrace with a provided type to the crash report - */ -- (void)attachCustomStacktrace:(NSArray *_Nonnull)frames - withType:(NSString *_Nonnull)type; - -/** - * Returns the enhanced error message for the thread, or nil if none exists. - */ -- (NSString *_Nullable)enhancedErrorMessageForThread:(NSDictionary *_Nullable)thread __deprecated; - // ----------------------------------------------------------------------------- // MARK: - Metadata // ----------------------------------------------------------------------------- @@ -189,10 +133,6 @@ __deprecated_msg("Use toJson: instead."); // MARK: - Properties // ----------------------------------------------------------------------------- -/** - * The release stages used to notify at the time this report is captured - */ -@property(readwrite, copy, nullable) NSArray *notifyReleaseStages; /** * A loose representation of what was happening in the application at the time * of the event @@ -227,10 +167,6 @@ __deprecated_msg("Use toJson: instead."); * generates a section on bugsnag, displaying key/value pairs */ @property(readwrite, copy, nonnull) NSDictionary *metadata; -/** - * The event state (whether the error is handled/unhandled) - */ -@property(readonly, nonnull) BugsnagHandledState *handledState; /** * A per-event override for the apiKey. @@ -238,20 +174,6 @@ __deprecated_msg("Use toJson: instead."); * - Writes are not persisted to BugsnagConfiguration. */ @property(readwrite, copy, nonnull) NSString *apiKey; - -/** - * Property overrides - */ -@property(readonly, copy, nonnull) NSDictionary *overrides; -/** - * Number of frames to discard at the top of the generated stacktrace. - * Stacktraces from raised exceptions are unaffected. - */ -@property(readwrite) NSUInteger depth; -/** - * Raw error data - */ -@property(readwrite, copy, nullable) NSDictionary *error; /** * Device information such as OS name and version */ @@ -269,9 +191,4 @@ __deprecated_msg("Use toJson: instead."); */ @property(readwrite, copy, nullable) NSDictionary *appState; -/** - * If YES, a complete report was not able to be obtained at generation time - */ -@property (readonly, nonatomic, getter=isIncomplete) BOOL incomplete; - @end diff --git a/Source/BugsnagEvent.m b/Source/BugsnagEvent.m index 059890e5b..679187322 100644 --- a/Source/BugsnagEvent.m +++ b/Source/BugsnagEvent.m @@ -178,25 +178,6 @@ id BSGLoadConfigValue(NSDictionary *report, NSString *valueName) { ?: BSGLoadConfigValue(report, @"releaseStage"); } -BSGSeverity BSGParseSeverity(NSString *severity) { - if ([severity isEqualToString:BSGKeyInfo]) - return BSGSeverityInfo; - else if ([severity isEqualToString:BSGKeyWarning]) - return BSGSeverityWarning; - return BSGSeverityError; -} - -NSString *BSGFormatSeverity(BSGSeverity severity) { - switch (severity) { - case BSGSeverityInfo: - return BSGKeyInfo; - case BSGSeverityError: - return BSGKeyError; - case BSGSeverityWarning: - return BSGKeyWarning; - } -} - NSDictionary *BSGParseCustomException(NSDictionary *report, NSString *errorClass, NSString *message) { id frames = @@ -259,7 +240,41 @@ @interface BugsnagEvent () @property(nonatomic, readwrite, copy, nullable) NSDictionary *customException; @property(nonatomic, strong) BugsnagSession *session; -@property (nonatomic, readwrite, getter=isIncomplete) BOOL incomplete; +/** + * The event state (whether the error is handled/unhandled) + */ +@property(readonly, nonnull) BugsnagHandledState *handledState; + +- (NSDictionary *_Nonnull)toJson; + +/** + * Whether this report should be sent, based on release stage information + * cached at crash time and within the application currently + * + * @return YES if the report should be sent + */ +- (BOOL)shouldBeSent; + +/** + * The release stages used to notify at the time this report is captured + */ +@property(readwrite, copy, nullable) NSArray *notifyReleaseStages; + +/** + * Property overrides + */ +@property(readonly, copy, nonnull) NSDictionary *overrides; + +/** + * Number of frames to discard at the top of the generated stacktrace. + * Stacktraces from raised exceptions are unaffected. + */ +@property(readwrite) NSUInteger depth; + +/** + * Raw error data + */ +@property(readwrite, copy, nullable) NSDictionary *error; @end @implementation BugsnagEvent @@ -555,11 +570,6 @@ - (void)setReleaseStage:(NSString *)releaseStage { } } -- (void)attachCustomStacktrace:(NSArray *)frames withType:(NSString *)type { - [self setOverrideProperty:@"customStacktraceFrames" value:frames]; - [self setOverrideProperty:@"customStacktraceType" value:type]; -} - @synthesize severity = _severity; - (BSGSeverity)severity { @@ -602,11 +612,6 @@ - (void)setOverrideProperty:(NSString *)key value:(id)value { } -- (NSDictionary *)serializableValueWithTopLevelData: - (NSMutableDictionary *)data { - return [self toJson]; -} - - (NSDictionary *)toJson { NSMutableDictionary *event = [NSMutableDictionary dictionary]; NSMutableDictionary *metadata = [[self metadata] mutableCopy]; @@ -761,10 +766,6 @@ - (void)serialiseThread:(NSMutableArray *)bugsnagThreads BSGArrayAddSafeObject(bugsnagThreads, threadDict); } -- (NSString *_Nullable)enhancedErrorMessageForThread:(NSDictionary *_Nullable)thread { - return [self errorMessage]; -} - @end @implementation RegisterErrorData diff --git a/Source/BugsnagHandledState.h b/Source/BugsnagHandledState.h index 202040040..1aeb90d7e 100644 --- a/Source/BugsnagHandledState.h +++ b/Source/BugsnagHandledState.h @@ -21,6 +21,25 @@ typedef NS_ENUM(NSUInteger, SeverityReasonType) { LikelyOutOfMemory, }; +/** + * Convert a string to a severity value + * + * @param severity Intended severity value, such as info, warning, or error + * + * @return converted severity level or BSGSeverityError if no conversion is + * found + */ +BSGSeverity BSGParseSeverity(NSString *severity); + +/** + * Serialize a severity for JSON payloads + * + * @param severity a severity + * + * @return the equivalent string value + */ +NSString *BSGFormatSeverity(BSGSeverity severity); + @interface BugsnagHandledState : NSObject @property(nonatomic, readonly) BOOL unhandled; diff --git a/Source/BugsnagHandledState.m b/Source/BugsnagHandledState.m index 5152dc463..8a07eb517 100644 --- a/Source/BugsnagHandledState.m +++ b/Source/BugsnagHandledState.m @@ -7,6 +7,26 @@ // #import "BugsnagHandledState.h" +#import "BugsnagKeys.h" + +BSGSeverity BSGParseSeverity(NSString *severity) { + if ([severity isEqualToString:BSGKeyInfo]) + return BSGSeverityInfo; + else if ([severity isEqualToString:BSGKeyWarning]) + return BSGSeverityWarning; + return BSGSeverityError; +} + +NSString *BSGFormatSeverity(BSGSeverity severity) { + switch (severity) { + case BSGSeverityInfo: + return BSGKeyInfo; + case BSGSeverityError: + return BSGKeyError; + case BSGSeverityWarning: + return BSGKeyWarning; + } +} static NSString *const kUnhandled = @"unhandled"; static NSString *const kSeverityReasonType = @"severityReasonType"; diff --git a/Source/BugsnagSink.m b/Source/BugsnagSink.m index 8ca45a049..2c233f8f0 100644 --- a/Source/BugsnagSink.m +++ b/Source/BugsnagSink.m @@ -39,6 +39,11 @@ @interface Bugsnag () + (BugsnagClient *)client; @end +@interface BugsnagEvent () +- (NSDictionary *_Nonnull)toJson; +- (BOOL)shouldBeSent; +@end + @interface BugsnagConfiguration () @property(nonatomic, readwrite, strong) NSMutableArray *onSendBlocks; @end diff --git a/Tests/BugsnagEventTests.m b/Tests/BugsnagEventTests.m index f9a2713ca..97bc8540f 100644 --- a/Tests/BugsnagEventTests.m +++ b/Tests/BugsnagEventTests.m @@ -21,6 +21,12 @@ @interface Bugsnag () + (BugsnagConfiguration *)configuration; @end +@interface BugsnagEvent () +- (NSDictionary *_Nonnull)toJson; +- (BOOL)shouldBeSent; +@property(readwrite) NSUInteger depth; +@end + @interface BugsnagEventTests : BugsnagBaseUnitTest @end diff --git a/UPGRADING.md b/UPGRADING.md index ceb34d91c..c32522f37 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -170,3 +170,21 @@ of the removed `addAttribute`: - BugsnagCrashReport.addAttribute(_:withValue:toTabWithName:) + BugsnagEvent.addMetadata(sectionName:key:value:) ``` + +#### Removals + +```diff +- BSGParseSeverity +- BSGFormatSeverity +- [event serializableValueWithTopLevelData:] +- [event shouldBeSent:] +- [event toJson:] +- [event attachCustomStacktrace:withType:] +- [event enhancedErrorMessageForThread:] +- event.notifyReleaseStages +- event.handledState +- event.overrides +- event.depth +- event.error +- event.isIncomplete +``` diff --git a/features/cross_notifier_notify.feature b/features/cross_notifier_notify.feature index 3aa8a8797..c1f6acdb9 100644 --- a/features/cross_notifier_notify.feature +++ b/features/cross_notifier_notify.feature @@ -6,7 +6,7 @@ Feature: Communicating events between notifiers using bugsnag-cocoa as the delivery layer. Scenario: Report a handled event through internalNotify() - Report a handled exception, including a custom stacktrace and severity. + Report a handled exception, including a custom severity. Event counts in the report's session should match the handled-ness. When I run "HandledInternalNotifyScenario" @@ -15,19 +15,8 @@ Feature: Communicating events between notifiers And request 1 is valid for the error reporting API And the exception "errorClass" equals "Handled Error!" for request 1 And the exception "message" equals "Internally reported a handled event" for request 1 - And the exception "type" equals "unreal" for request 1 And the event "severity" equals "warning" for request 1 And the event "severityReason.type" equals "handledException" for request 1 - - And the "method" of stack frame 0 equals "foo()" for request 1 - And the "file" of stack frame 0 equals "src/Giraffe.mm" for request 1 - And the "lineNumber" of stack frame 0 equals 200 for request 1 - And the "method" of stack frame 1 equals "bar()" for request 1 - And the "file" of stack frame 1 equals "parser.js" for request 1 - And the "lineNumber" of stack frame 1 is null for request 1 - And the "method" of stack frame 2 equals "yes()" for request 1 - And the "file" of stack frame 2 is null for request 1 - And the "lineNumber" of stack frame 2 is null for request 1 And the event "unhandled" is false for request 1 And the payload field "events" is an array with 1 element for request 1 @@ -36,7 +25,7 @@ Feature: Communicating events between notifiers And the payload field "events.0.session.id" of request 1 equals the payload field "sessions.0.id" of request 0 Scenario: Report an unhandled event through internalNotify() - Report an unhandled exception, including a custom stacktrace and severity. + Report an unhandled exception, including a custom severity. Event counts in the report's session should match the handled-ness. When I run "UnhandledInternalNotifyScenario" @@ -45,19 +34,8 @@ Feature: Communicating events between notifiers And request 1 is valid for the error reporting API And the exception "errorClass" equals "Unhandled Error?!" for request 1 And the exception "message" equals "Internally reported an unhandled event" for request 1 - And the exception "type" equals "fake" for request 1 And the event "severity" equals "info" for request 1 And the event "severityReason.type" equals "userCallbackSetSeverity" for request 1 - - And the "method" of stack frame 0 equals "bar()" for request 1 - And the "file" of stack frame 0 equals "foo.js" for request 1 - And the "lineNumber" of stack frame 0 equals 43 for request 1 - And the "method" of stack frame 1 equals "baz()" for request 1 - And the "file" of stack frame 1 equals "[native code]" for request 1 - And the "lineNumber" of stack frame 1 is null for request 1 - And the "method" of stack frame 2 equals "is_done()" for request 1 - And the "file" of stack frame 2 is null for request 1 - And the "lineNumber" of stack frame 2 is null for request 1 And the event "unhandled" is true for request 1 And the payload field "events" is an array with 1 element for request 1 diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledErrorOverrideScenario.swift b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledErrorOverrideScenario.swift index 36d399d6c..8833318f4 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledErrorOverrideScenario.swift +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledErrorOverrideScenario.swift @@ -8,8 +8,6 @@ import Bugsnag /** Sends a handled Error to Bugsnag and overrides the exception name + message - Demonstrates adjusting report depth to exclude common error handling code from grouping - See: https://docs.bugsnag.com/platforms/ios-objc/reporting-handled-exceptions/#depth */ class HandledErrorOverrideScenario: Scenario { @@ -22,7 +20,6 @@ class HandledErrorOverrideScenario: Scenario { Bugsnag.notifyError(error) { report in report.errorMessage = "Foo" report.errorClass = "Bar" - report.depth += 2 report.metadata["account"] = [ "items": [400,200] ] diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledInternalNotifyScenario.swift b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledInternalNotifyScenario.swift index eddd2a3c8..27b6556d2 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledInternalNotifyScenario.swift +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledInternalNotifyScenario.swift @@ -19,7 +19,6 @@ import Bugsnag ["method":"bar()", "file":"parser.js"], ["method":"yes()"] ] - report.attachCustomStacktrace(frames, withType: "unreal") } } } diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/UnhandledInternalNotifyScenario.swift b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/UnhandledInternalNotifyScenario.swift index f92992ecb..f8b451f89 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/UnhandledInternalNotifyScenario.swift +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/UnhandledInternalNotifyScenario.swift @@ -19,7 +19,6 @@ import Bugsnag ["method":"baz()", "file":"[native code]"], ["method":"is_done()"] ] - report.attachCustomStacktrace(frames, withType: "fake") } } } diff --git a/features/handled_errors.feature b/features/handled_errors.feature index e0edb3841..4089602a5 100644 --- a/features/handled_errors.feature +++ b/features/handled_errors.feature @@ -18,8 +18,6 @@ Scenario: Override errorClass and message from a notifyError() callback, customi And the event "device.time" is within 30 seconds of the current timestamp And the event "metaData.account.items.0" equals 400 And the event "metaData.account.items.1" equals 200 - And the "method" of stack frame 0 demangles to "iOSTestApp.HandledErrorOverrideScenario.run() -> ()" - And the stack trace is an array with 15 stack frames Scenario: Reporting an NSError When I run "HandledErrorScenario" diff --git a/iOS/BugsnagTests/BugsnagEventFromKSCrashReportTest.m b/iOS/BugsnagTests/BugsnagEventFromKSCrashReportTest.m index 2d174137e..4e3be64ed 100644 --- a/iOS/BugsnagTests/BugsnagEventFromKSCrashReportTest.m +++ b/iOS/BugsnagTests/BugsnagEventFromKSCrashReportTest.m @@ -13,6 +13,13 @@ @interface BugsnagEventFromKSCrashReportTest : XCTestCase @property BugsnagEvent *report; @end +@interface BugsnagEvent () +- (NSDictionary *_Nonnull)toJson; +- (BOOL)shouldBeSent; +@property(readwrite, copy, nullable) NSArray *notifyReleaseStages; +@property(readwrite) NSUInteger depth; +@end + @implementation BugsnagEventFromKSCrashReportTest - (void)setUp { From 999984df628ec31f0a1de70b5dec8bc4846995c0 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Fri, 27 Mar 2020 11:09:01 +0000 Subject: [PATCH 2/2] reinstate attachCustomStacktrace method after review feedback --- Source/BugsnagEvent.h | 6 +++++ Source/BugsnagEvent.m | 5 ++++ UPGRADING.md | 1 - features/cross_notifier_notify.feature | 26 +++++++++++++++++-- .../HandledErrorOverrideScenario.swift | 4 +++ .../HandledInternalNotifyScenario.swift | 1 + .../UnhandledInternalNotifyScenario.swift | 1 + features/handled_errors.feature | 2 ++ 8 files changed, 43 insertions(+), 3 deletions(-) diff --git a/Source/BugsnagEvent.h b/Source/BugsnagEvent.h index edd879a07..b43073a58 100644 --- a/Source/BugsnagEvent.h +++ b/Source/BugsnagEvent.h @@ -69,6 +69,12 @@ initWithErrorName:(NSString *_Nonnull)name handledState:(BugsnagHandledState *_Nonnull)handledState session:(BugsnagSession *_Nullable)session; +/** + * Prepend a custom stacktrace with a provided type to the crash report + */ +- (void)attachCustomStacktrace:(NSArray *_Nonnull)frames + withType:(NSString *_Nonnull)type; + // ----------------------------------------------------------------------------- // MARK: - Metadata // ----------------------------------------------------------------------------- diff --git a/Source/BugsnagEvent.m b/Source/BugsnagEvent.m index 679187322..8ee0a436e 100644 --- a/Source/BugsnagEvent.m +++ b/Source/BugsnagEvent.m @@ -570,6 +570,11 @@ - (void)setReleaseStage:(NSString *)releaseStage { } } +- (void)attachCustomStacktrace:(NSArray *)frames withType:(NSString *)type { + [self setOverrideProperty:@"customStacktraceFrames" value:frames]; + [self setOverrideProperty:@"customStacktraceType" value:type]; +} + @synthesize severity = _severity; - (BSGSeverity)severity { diff --git a/UPGRADING.md b/UPGRADING.md index 583490c60..4d1847dbe 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -188,7 +188,6 @@ of the removed `addAttribute`: - [event serializableValueWithTopLevelData:] - [event shouldBeSent:] - [event toJson:] -- [event attachCustomStacktrace:withType:] - [event enhancedErrorMessageForThread:] - event.notifyReleaseStages - event.handledState diff --git a/features/cross_notifier_notify.feature b/features/cross_notifier_notify.feature index c1f6acdb9..3aa8a8797 100644 --- a/features/cross_notifier_notify.feature +++ b/features/cross_notifier_notify.feature @@ -6,7 +6,7 @@ Feature: Communicating events between notifiers using bugsnag-cocoa as the delivery layer. Scenario: Report a handled event through internalNotify() - Report a handled exception, including a custom severity. + Report a handled exception, including a custom stacktrace and severity. Event counts in the report's session should match the handled-ness. When I run "HandledInternalNotifyScenario" @@ -15,8 +15,19 @@ Feature: Communicating events between notifiers And request 1 is valid for the error reporting API And the exception "errorClass" equals "Handled Error!" for request 1 And the exception "message" equals "Internally reported a handled event" for request 1 + And the exception "type" equals "unreal" for request 1 And the event "severity" equals "warning" for request 1 And the event "severityReason.type" equals "handledException" for request 1 + + And the "method" of stack frame 0 equals "foo()" for request 1 + And the "file" of stack frame 0 equals "src/Giraffe.mm" for request 1 + And the "lineNumber" of stack frame 0 equals 200 for request 1 + And the "method" of stack frame 1 equals "bar()" for request 1 + And the "file" of stack frame 1 equals "parser.js" for request 1 + And the "lineNumber" of stack frame 1 is null for request 1 + And the "method" of stack frame 2 equals "yes()" for request 1 + And the "file" of stack frame 2 is null for request 1 + And the "lineNumber" of stack frame 2 is null for request 1 And the event "unhandled" is false for request 1 And the payload field "events" is an array with 1 element for request 1 @@ -25,7 +36,7 @@ Feature: Communicating events between notifiers And the payload field "events.0.session.id" of request 1 equals the payload field "sessions.0.id" of request 0 Scenario: Report an unhandled event through internalNotify() - Report an unhandled exception, including a custom severity. + Report an unhandled exception, including a custom stacktrace and severity. Event counts in the report's session should match the handled-ness. When I run "UnhandledInternalNotifyScenario" @@ -34,8 +45,19 @@ Feature: Communicating events between notifiers And request 1 is valid for the error reporting API And the exception "errorClass" equals "Unhandled Error?!" for request 1 And the exception "message" equals "Internally reported an unhandled event" for request 1 + And the exception "type" equals "fake" for request 1 And the event "severity" equals "info" for request 1 And the event "severityReason.type" equals "userCallbackSetSeverity" for request 1 + + And the "method" of stack frame 0 equals "bar()" for request 1 + And the "file" of stack frame 0 equals "foo.js" for request 1 + And the "lineNumber" of stack frame 0 equals 43 for request 1 + And the "method" of stack frame 1 equals "baz()" for request 1 + And the "file" of stack frame 1 equals "[native code]" for request 1 + And the "lineNumber" of stack frame 1 is null for request 1 + And the "method" of stack frame 2 equals "is_done()" for request 1 + And the "file" of stack frame 2 is null for request 1 + And the "lineNumber" of stack frame 2 is null for request 1 And the event "unhandled" is true for request 1 And the payload field "events" is an array with 1 element for request 1 diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledErrorOverrideScenario.swift b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledErrorOverrideScenario.swift index 8833318f4..387a4213e 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledErrorOverrideScenario.swift +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledErrorOverrideScenario.swift @@ -8,6 +8,8 @@ import Bugsnag /** Sends a handled Error to Bugsnag and overrides the exception name + message + Demonstrates adjusting report depth to exclude common error handling code from grouping + See: https://docs.bugsnag.com/platforms/ios-objc/reporting-handled-exceptions/#depth */ class HandledErrorOverrideScenario: Scenario { @@ -20,6 +22,8 @@ class HandledErrorOverrideScenario: Scenario { Bugsnag.notifyError(error) { report in report.errorMessage = "Foo" report.errorClass = "Bar" + var depth: Int = report.value(forKey: "depth") as! Int + report.setValue(depth + 2, forKey: "depth") report.metadata["account"] = [ "items": [400,200] ] diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledInternalNotifyScenario.swift b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledInternalNotifyScenario.swift index 27b6556d2..eddd2a3c8 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledInternalNotifyScenario.swift +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/HandledInternalNotifyScenario.swift @@ -19,6 +19,7 @@ import Bugsnag ["method":"bar()", "file":"parser.js"], ["method":"yes()"] ] + report.attachCustomStacktrace(frames, withType: "unreal") } } } diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/UnhandledInternalNotifyScenario.swift b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/UnhandledInternalNotifyScenario.swift index f8b451f89..f92992ecb 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/UnhandledInternalNotifyScenario.swift +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/UnhandledInternalNotifyScenario.swift @@ -19,6 +19,7 @@ import Bugsnag ["method":"baz()", "file":"[native code]"], ["method":"is_done()"] ] + report.attachCustomStacktrace(frames, withType: "fake") } } } diff --git a/features/handled_errors.feature b/features/handled_errors.feature index 4089602a5..e0edb3841 100644 --- a/features/handled_errors.feature +++ b/features/handled_errors.feature @@ -18,6 +18,8 @@ Scenario: Override errorClass and message from a notifyError() callback, customi And the event "device.time" is within 30 seconds of the current timestamp And the event "metaData.account.items.0" equals 400 And the event "metaData.account.items.1" equals 200 + And the "method" of stack frame 0 demangles to "iOSTestApp.HandledErrorOverrideScenario.run() -> ()" + And the stack trace is an array with 15 stack frames Scenario: Reporting an NSError When I run "HandledErrorScenario"