Skip to content
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
99 changes: 90 additions & 9 deletions ios/RNSentry.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,40 @@ + (NSRegularExpression *)frameRegex {
NSRange searchedRange = NSMakeRange(0, [line length]);
NSArray *matches = [[RNSentry frameRegex] matchesInString:line options:0 range:searchedRange];
for (NSTextCheckingResult *match in matches) {
NSString *matchText = [line substringWithRange:[match range]];
[frames addObject:@{
@"methodName": [line substringWithRange:[match rangeAtIndex:1]],
@"column": [formatter numberFromString:[line substringWithRange:[match rangeAtIndex:4]]],
@"lineNumber": [formatter numberFromString:[line substringWithRange:[match rangeAtIndex:3]]],
@"lineNumber": [formatter numberFromString:[line substringWithRange:[match rangeAtIndex:3]]],
@"file": [line substringWithRange:[match rangeAtIndex:2]]
}];
}
}
return frames;
}

NSArray *SentryParseRavenFrames(NSArray *ravenFrames) {
NSNumberFormatter *formatter = [RNSentry numberFormatter];
NSMutableArray *frames = [NSMutableArray array];
for (NSDictionary *ravenFrame in ravenFrames) {
if (ravenFrame[@"lineno"] != NSNull.null) {
[frames addObject:@{
@"methodName": ravenFrame[@"function"],
@"column": [formatter numberFromString:[NSString stringWithFormat:@"%@", ravenFrame[@"colno"]]],
@"lineNumber": [formatter numberFromString:[NSString stringWithFormat:@"%@", ravenFrame[@"lineno"]]],
@"file": ravenFrame[@"filename"]
}];
}
}
return frames;
}

RCT_EXPORT_MODULE()

- (NSDictionary<NSString *, id> *)constantsToExport
{
return @{@"nativeClientAvailable": @YES};
}


RCT_EXPORT_METHOD(startWithDsnString:(NSString * _Nonnull)dsnString)
{
[SentryClient setShared:[[SentryClient alloc] initWithDsnString:dsnString]];
Expand Down Expand Up @@ -109,24 +123,26 @@ + (NSRegularExpression *)frameRegex {
resolve(@YES);
}

RCT_EXPORT_METHOD(captureMessage:(NSString * _Nonnull)message level:(int)level)
RCT_EXPORT_METHOD(clearContext)
{
[[SentryClient shared] captureMessage:message level:level];
[SentryClient shared].tags = @{};
[SentryClient shared].extra = @{};
[SentryClient shared].user = nil;
}

RCT_EXPORT_METHOD(setLogLevel:(int)level)
{
[SentryClient setLogLevel:level];
}

RCT_EXPORT_METHOD(setExtras:(NSDictionary * _Nonnull)extras)
RCT_EXPORT_METHOD(setTags:(NSDictionary * _Nonnull)tags)
{
[SentryClient shared].extra = extras;
[SentryClient shared].tags = [self sanitizeDictionary:tags];
}

RCT_EXPORT_METHOD(setTags:(NSDictionary * _Nonnull)tags)
RCT_EXPORT_METHOD(setExtra:(NSDictionary * _Nonnull)extra)
{
[SentryClient shared].tags = [self sanitizeDictionary:tags];
[SentryClient shared].extra = extra;
}

RCT_EXPORT_METHOD(setUser:(NSDictionary * _Nonnull)user)
Expand All @@ -137,11 +153,76 @@ + (NSRegularExpression *)frameRegex {
extra:[RCTConvert NSDictionary:user[@"extra"]]];
}

RCT_EXPORT_METHOD(captureBreadcrumb:(NSDictionary * _Nonnull)breadcrumb)
{
SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithCategory:breadcrumb[@"category"]
timestamp:[NSDate dateWithTimeIntervalSince1970:[breadcrumb[@"timestamp"] integerValue]]
message:breadcrumb[@"message"]
type:nil
level:[self sentrySeverityFromLevel:[breadcrumb[@"level"] integerValue]]
data:nil];
[[SentryClient shared].breadcrumbs add:crumb];
}

RCT_EXPORT_METHOD(captureEvent:(NSDictionary * _Nonnull)event)
{
SentrySeverity level = [self sentrySeverityFromLevel:[event[@"level"] integerValue]];

SentryUser *user = nil;
if (event[@"user"] != nil) {
user = [[SentryUser alloc] initWithId:[RCTConvert NSString:event[@"user"][@"userID"]]
email:[RCTConvert NSString:event[@"user"][@"email"]]
username:[RCTConvert NSString:event[@"user"][@"username"]]
extra:[RCTConvert NSDictionary:event[@"user"][@"extra"]]];
}

if (event[@"message"]) {
SentryEvent *sentryEvent = [[SentryEvent alloc] init:event[@"message"]
timestamp:[NSDate date]
level:level
logger:event[@"logger"]
culprit:nil
serverName:nil
release:nil
buildNumber:nil
tags:[self sanitizeDictionary:event[@"tags"]]
modules:nil
extra:event[@"extra"]
fingerprint:nil
user:user
exceptions:nil
stacktrace:nil];
[[SentryClient shared] captureEvent:sentryEvent];
} else if (event[@"exception"]) {
// TODO what do we do here with extra/tags/users that are not global?
[self handleSoftJSExceptionWithMessage:[NSString stringWithFormat:@"Unhandled JS Exception: %@", event[@"exception"][@"values"][0][@"value"]]
stack:SentryParseRavenFrames(event[@"exception"][@"values"][0][@"stacktrace"][@"frames"])
exceptionId:@99];
}

}

RCT_EXPORT_METHOD(crash)
{
[[SentryClient shared] crash];
}

- (SentrySeverity)sentrySeverityFromLevel:(NSInteger)level {
switch (level) {
case 0:
return SentrySeverityFatal;
case 2:
return SentrySeverityWarning;
case 3:
return SentrySeverityInfo;
case 4:
return SentrySeverityDebug;
default:
return SentrySeverityError;
}
return level;
}

- (NSDictionary *)sanitizeDictionary:(NSDictionary *)dictionary {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *key in dictionary.allKeys) {
Expand Down
Loading