-
Notifications
You must be signed in to change notification settings - Fork 216
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
Track all errors in Sentry #1558
Conversation
@@ -153,7 +153,8 @@ - (void)checkAndStartWithKeyBackupVersion:(nullable MXKeyBackupVersion*)keyBacku | |||
Class<MXKeyBackupAlgorithm> algorithmClass = AlgorithmClassesByName[keyBackupVersion.algorithm]; | |||
if (algorithmClass == NULL) | |||
{ | |||
MXLogError(@"[MXKeyBackup] checkAndStartWithKeyBackupVersion: unknown algorithm: %@", keyBackupVersion.algorithm); | |||
NSString *message = [NSString stringWithFormat:@"[MXKeyBackup] checkAndStartWithKeyBackupVersion: unknown algorithm: %@", keyBackupVersion.algorithm]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some cases the variable is one of very few and it is okay making it a part of the message itself (objc has no StaticString
equivalent, so this works)
@@ -653,7 +661,12 @@ - (MXEventDecryptionResult *)decryptEvent2:(MXEvent *)event inTimeline:(NSString | |||
result = [alg decryptEvent:event inTimeline:timeline]; | |||
if (result.error) | |||
{ | |||
MXLogError(@"[MXCrypto] decryptEvent: Error for %@: %@\nEvent: %@", event.eventId, result.error, event.JSONDictionary); | |||
NSDictionary *details = @{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Annoyingly objc will crash if we ever add nil
value to a dictionary, meaning it is safer to always default to something rather than risk logs crashing the app
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whereabouts does this crash actually happen? I'm wondering if there would be an opportune place we could map all of the nil
values in the dictionary into @"unknown"
before the crash takes place?
Otherwise it kind of feels like it would be an easy place for someone to introduce a crash by either not knowing this pitfall, or by not realising a value is nullable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is the actual construction of dictionary, for example this will crash:
NSString *value = nil;
NSDictionary *dict = @{
@"value": value // If I passed nil here directly the compiler would catch it
};
So we can't really put any kind of safety wrapper around it. The rest of the codebase has this issue as well but is seems we rarely have unexpected nil values. My justification for allowing this was that most new code we write is in swift and thus we won't be really adding new dictionary contexts in objective-c, but of course I could be wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL that this is standard objc behaviour! Ignore me 🤐
Codecov Report
@@ Coverage Diff @@
## develop #1558 +/- ##
===========================================
- Coverage 45.25% 45.17% -0.08%
===========================================
Files 520 521 +1
Lines 84791 84957 +166
Branches 37520 37500 -20
===========================================
+ Hits 38369 38381 +12
- Misses 45320 45476 +156
+ Partials 1102 1100 -2
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a great change overall to me 😎
@@ -552,7 +554,9 @@ - (void)setIsEncrypted:(BOOL)isEncrypted | |||
// This should never happen | |||
if (_isEncrypted && !isEncrypted) | |||
{ | |||
MXLogError(@"[MXRoomSummary] setIsEncrypted: Attempt to reset isEncrypted for room %@. Ignote it. Call stack: %@", self.roomId, [NSThread callStackSymbols]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm presuming we don't need to worry about call stacks now that these go to Sentry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly, though it will be missing from rageshake files ... I think that is okay?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep yep, makes sense to me 👍
@@ -993,7 +993,7 @@ - (RoomReceiptsStore*)getOrCreateRoomReceiptsStore:(NSString *)roomId | |||
@"roomId": roomId ?: @"", | |||
@"exception": exception | |||
}; | |||
MXLogErrorWithDetails(@"[MXFileStore] Warning: loadReceipts file for room as been corrupted", logDetails); | |||
// MXLogErrorWithDetails(@"[MXFileStore] Warning: loadReceipts file for room as been corrupted", logDetails); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this intentionally left commented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops sorry, thanks
import SwiftyBeaver | ||
|
||
/// SwiftyBeaver log destination that sends errors to analytics tracker | ||
class AnalyticsDestination: BaseDestination { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be MXAnalyticsDestination
?
MatrixSDK/Utils/Logs/MXLog.h
Outdated
} | ||
|
||
// TODO: failure context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that todo different to the MXLogFailure
s above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed that, thanks 🤦
MatrixSDK/Utils/Logs/MXLog.swift
Outdated
|
||
/// Log failure with additional details | ||
/// | ||
/// A failure is any type of programming error which should never occur in production. In `DEBUG` confuguration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// A failure is any type of programming error which should never occur in production. In `DEBUG` confuguration | |
/// A failure is any type of programming error which should never occur in production. In `DEBUG` configuration |
MatrixSDK/Utils/Logs/MXLog.swift
Outdated
} | ||
} | ||
|
||
/// Convenience wrapper around `MXLog` which formats all logs as "[Name] function: <message>" | ||
/// | ||
/// Note: Ideallly the `format` of `ConsoleDestination` is set to track filename and function automatically |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Note: Ideallly the `format` of `ConsoleDestination` is set to track filename and function automatically | |
/// Note: Ideally the `format` of `ConsoleDestination` is set to track filename and function automatically |
@@ -653,7 +661,12 @@ - (MXEventDecryptionResult *)decryptEvent2:(MXEvent *)event inTimeline:(NSString | |||
result = [alg decryptEvent:event inTimeline:timeline]; | |||
if (result.error) | |||
{ | |||
MXLogError(@"[MXCrypto] decryptEvent: Error for %@: %@\nEvent: %@", event.eventId, result.error, event.JSONDictionary); | |||
NSDictionary *details = @{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whereabouts does this crash actually happen? I'm wondering if there would be an opportune place we could map all of the nil
values in the dictionary into @"unknown"
before the crash takes place?
Otherwise it kind of feels like it would be an easy place for someone to introduce a crash by either not knowing this pitfall, or by not realising a value is nullable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
Following up on #1517, which tracked only some of
MXLogError
andMXLogFailure
in analytics (Sentry for element-ios, assuming user consent), this PR extends this approach across the entire SDK and makes each error / failure trackable. This requires a number of changes:AnalyticsDestination
toMXLog
which sends errors toAnalyticsDelegate
. Previous implementation simply hooked into the existing error methods and was a little hacky. Using destinations is the preffered approachStaticString
instead ofString
, meaning no variables can be present in the message. This may sound annoying but will make tracing of parameters more explicit by:details
argument with existingcontext
argument that can be of any type. This is to both reduce the number of arguments as well as stay consistent with SwiftyBeaver