Skip to content

Commit 4bc69cf

Browse files
fix(ios): setUser to null works with null introduced in RN 0.77.1 (#4567)
1 parent d09472b commit 4bc69cf

File tree

5 files changed

+167
-17
lines changed

5 files changed

+167
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
- Remove `error:` prefix from `collect-modules.sh` to avoid failing iOS builds ([#4570](https://github.com/getsentry/sentry-react-native/pull/4570))
3434
- Sentry Module Collection Script Fails with Spaces in Node Path on iOS ([#4559](https://github.com/getsentry/sentry-react-native/pull/4559))
3535
- Various crashes and issues of Session Replay on Android. See the Android SDK version bump for more details. ([#4529](https://github.com/getsentry/sentry-react-native/pull/4529))
36+
- `Sentry.setUser(null)` doesn't crash on iOS with RN 0.77.1 ([#4567](https://github.com/getsentry/sentry-react-native/pull/4567))
3637

3738
### Dependencies
3839

packages/core/RNSentryCocoaTester/RNSentryCocoaTester.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
332D33472CDBDBB600547D76 /* RNSentryReplayOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 332D33462CDBDBB600547D76 /* RNSentryReplayOptionsTests.swift */; };
11+
3339C4812D6625570088EB3A /* RNSentryUserTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3339C4802D6625570088EB3A /* RNSentryUserTests.mm */; };
1112
336084392C32E382008CC412 /* RNSentryReplayBreadcrumbConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 336084382C32E382008CC412 /* RNSentryReplayBreadcrumbConverterTests.swift */; };
1213
3380C6C42CE25ECA0018B9B6 /* RNSentryReplayPostInitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3380C6C32CE25ECA0018B9B6 /* RNSentryReplayPostInitTests.swift */; };
1314
33958C692BFCF12600AD1FB6 /* RNSentryOnDrawReporterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33958C682BFCF12600AD1FB6 /* RNSentryOnDrawReporterTests.m */; };
@@ -25,6 +26,8 @@
2526
332D33482CDBDC7300547D76 /* RNSentry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNSentry.h; path = ../ios/RNSentry.h; sourceTree = SOURCE_ROOT; };
2627
332D33492CDCC8E100547D76 /* RNSentryTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSentryTests.h; sourceTree = "<group>"; };
2728
332D334A2CDCC8EB00547D76 /* RNSentryCocoaTesterTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNSentryCocoaTesterTests-Bridging-Header.h"; sourceTree = "<group>"; };
29+
3339C47F2D6625260088EB3A /* RNSentry+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNSentry+Test.h"; sourceTree = "<group>"; };
30+
3339C4802D6625570088EB3A /* RNSentryUserTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = RNSentryUserTests.mm; sourceTree = "<group>"; };
2831
336084382C32E382008CC412 /* RNSentryReplayBreadcrumbConverterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RNSentryReplayBreadcrumbConverterTests.swift; sourceTree = "<group>"; };
2932
3360843A2C32E3A8008CC412 /* RNSentryReplayBreadcrumbConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSentryReplayBreadcrumbConverter.h; path = ../ios/RNSentryReplayBreadcrumbConverter.h; sourceTree = "<group>"; };
3033
3360843C2C340C76008CC412 /* RNSentryBreadcrumbTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNSentryBreadcrumbTests.swift; sourceTree = "<group>"; };
@@ -88,10 +91,12 @@
8891
3360899029524164007C7730 /* RNSentryCocoaTesterTests */ = {
8992
isa = PBXGroup;
9093
children = (
94+
3339C47F2D6625260088EB3A /* RNSentry+Test.h */,
9195
332D334A2CDCC8EB00547D76 /* RNSentryCocoaTesterTests-Bridging-Header.h */,
9296
332D33492CDCC8E100547D76 /* RNSentryTests.h */,
9397
336084382C32E382008CC412 /* RNSentryReplayBreadcrumbConverterTests.swift */,
9498
33F58ACF2977037D008F60EA /* RNSentryTests.mm */,
99+
3339C4802D6625570088EB3A /* RNSentryUserTests.mm */,
95100
33AFDFEC2B8D14B300AAB120 /* RNSentryFramesTrackerListenerTests.m */,
96101
33AFDFEE2B8D14C200AAB120 /* RNSentryFramesTrackerListenerTests.h */,
97102
33AFDFF02B8D15E500AAB120 /* RNSentryDependencyContainerTests.m */,
@@ -243,6 +248,7 @@
243248
336084392C32E382008CC412 /* RNSentryReplayBreadcrumbConverterTests.swift in Sources */,
244249
33F58AD02977037D008F60EA /* RNSentryTests.mm in Sources */,
245250
33958C692BFCF12600AD1FB6 /* RNSentryOnDrawReporterTests.m in Sources */,
251+
3339C4812D6625570088EB3A /* RNSentryUserTests.mm in Sources */,
246252
3380C6C42CE25ECA0018B9B6 /* RNSentryReplayPostInitTests.swift in Sources */,
247253
33AFDFED2B8D14B300AAB120 /* RNSentryFramesTrackerListenerTests.m in Sources */,
248254
);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#import <RNSentry/RNSentry.h>
2+
3+
@interface
4+
RNSentry (RNSentryInternal)
5+
6+
+ (SentryUser *_Nullable)userFrom:(NSDictionary *)userKeys
7+
otherUserKeys:(NSDictionary *)userDataKeys;
8+
9+
@end
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#import "RNSentry+Test.h"
2+
#import "RNSentryTests.h"
3+
#import <XCTest/XCTest.h>
4+
5+
@interface RNSentryUserTests : XCTestCase
6+
@end
7+
8+
@implementation RNSentryUserTests
9+
10+
- (void)testValidUser
11+
{
12+
SentryUser *expected = [[SentryUser alloc] init];
13+
[expected setUserId:@"123"];
14+
[expected setIpAddress:@"192.168.1.1"];
15+
[expected setEmail:@"[email protected]"];
16+
[expected setUsername:@"testuser"];
17+
[expected setSegment:@"testsegment"];
18+
[expected setData:@{
19+
@"foo" : @"bar",
20+
@"baz" : @123,
21+
@"qux" : @[ @"a", @"b", @"c" ],
22+
}];
23+
24+
SentryUser *actual = [RNSentry userFrom:@{
25+
@"id" : @"123",
26+
@"ip_address" : @"192.168.1.1",
27+
@"email" : @"[email protected]",
28+
@"username" : @"testuser",
29+
@"segment" : @"testsegment",
30+
}
31+
otherUserKeys:@{
32+
@"foo" : @"bar",
33+
@"baz" : @123,
34+
@"qux" : @[ @"a", @"b", @"c" ],
35+
}];
36+
37+
XCTAssertTrue([actual isEqualToUser:expected]);
38+
}
39+
40+
- (void)testNilUser
41+
{
42+
SentryUser *actual = [RNSentry userFrom:nil otherUserKeys:nil];
43+
XCTAssertNil(actual);
44+
}
45+
46+
- (void)testNullUser
47+
{
48+
SentryUser *actual = [RNSentry userFrom:(NSDictionary *)[NSNull null] otherUserKeys:nil];
49+
XCTAssertNil(actual);
50+
}
51+
52+
- (void)testEmptyUser
53+
{
54+
SentryUser *expected = [[SentryUser alloc] init];
55+
[expected setData:@{}];
56+
57+
SentryUser *actual = [RNSentry userFrom:@{} otherUserKeys:@{}];
58+
XCTAssertTrue([actual isEqualToUser:expected]);
59+
}
60+
61+
- (void)testInvalidUser
62+
{
63+
SentryUser *expected = [[SentryUser alloc] init];
64+
65+
SentryUser *actual = [RNSentry userFrom:@{
66+
@"id" : @123,
67+
@"ip_address" : @ {},
68+
@"email" : @ {},
69+
@"username" : @ {},
70+
@"segment" : @[],
71+
}
72+
otherUserKeys:nil];
73+
74+
XCTAssertTrue([actual isEqualToUser:expected]);
75+
}
76+
77+
- (void)testPartiallyInvalidUser
78+
{
79+
SentryUser *expected = [[SentryUser alloc] init];
80+
[expected setUserId:@"123"];
81+
82+
SentryUser *actual = [RNSentry userFrom:@{
83+
@"id" : @"123",
84+
@"ip_address" : @ {},
85+
@"email" : @ {},
86+
@"username" : @ {},
87+
@"segment" : @[],
88+
}
89+
otherUserKeys:nil];
90+
91+
XCTAssertTrue([actual isEqualToUser:expected]);
92+
}
93+
94+
- (void)testNullValuesUser
95+
{
96+
SentryUser *expected = [[SentryUser alloc] init];
97+
98+
SentryUser *actual = [RNSentry userFrom:@{
99+
@"id" : [NSNull null],
100+
@"ip_address" : [NSNull null],
101+
@"email" : [NSNull null],
102+
@"username" : [NSNull null],
103+
@"segment" : [NSNull null],
104+
}
105+
otherUserKeys:nil];
106+
107+
XCTAssertTrue([actual isEqualToUser:expected]);
108+
}
109+
110+
@end

packages/core/ios/RNSentry.mm

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -641,26 +641,50 @@ - (NSDictionary *)fetchNativeStackFramesBy:(NSArray<NSNumber *> *)instructionsAd
641641
RCT_EXPORT_METHOD(setUser : (NSDictionary *)userKeys otherUserKeys : (NSDictionary *)userDataKeys)
642642
{
643643
[SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
644-
if (nil == userKeys && nil == userDataKeys) {
645-
[scope setUser:nil];
646-
} else {
647-
SentryUser *userInstance = [[SentryUser alloc] init];
648-
649-
if (nil != userKeys) {
650-
[userInstance setUserId:userKeys[@"id"]];
651-
[userInstance setIpAddress:userKeys[@"ip_address"]];
652-
[userInstance setEmail:userKeys[@"email"]];
653-
[userInstance setUsername:userKeys[@"username"]];
654-
[userInstance setSegment:userKeys[@"segment"]];
655-
}
644+
[scope setUser:[RNSentry userFrom:userKeys otherUserKeys:userDataKeys]];
645+
}];
646+
}
656647

657-
if (nil != userDataKeys) {
658-
[userInstance setData:userDataKeys];
659-
}
648+
+ (SentryUser *_Nullable)userFrom:(NSDictionary *)userKeys
649+
otherUserKeys:(NSDictionary *)userDataKeys
650+
{
651+
// we can safely ignore userDataKeys since if original JS user was null userKeys will be null
652+
if ([userKeys isKindOfClass:NSDictionary.class]) {
653+
SentryUser *userInstance = [[SentryUser alloc] init];
660654

661-
[scope setUser:userInstance];
655+
id userId = [userKeys valueForKey:@"id"];
656+
if ([userId isKindOfClass:NSString.class]) {
657+
[userInstance setUserId:userId];
662658
}
663-
}];
659+
id ipAddress = [userKeys valueForKey:@"ip_address"];
660+
if ([ipAddress isKindOfClass:NSString.class]) {
661+
[userInstance setIpAddress:ipAddress];
662+
}
663+
id email = [userKeys valueForKey:@"email"];
664+
if ([email isKindOfClass:NSString.class]) {
665+
[userInstance setEmail:email];
666+
}
667+
id username = [userKeys valueForKey:@"username"];
668+
if ([username isKindOfClass:NSString.class]) {
669+
[userInstance setUsername:username];
670+
}
671+
id segment = [userKeys valueForKey:@"segment"];
672+
if ([segment isKindOfClass:NSString.class]) {
673+
[userInstance setSegment:segment];
674+
}
675+
676+
if ([userDataKeys isKindOfClass:NSDictionary.class]) {
677+
[userInstance setData:userDataKeys];
678+
}
679+
680+
return userInstance;
681+
}
682+
683+
if (![[NSNull null] isEqual:userKeys] && nil != userKeys) {
684+
NSLog(@"[RNSentry] Method setUser received unexpected type of userKeys.");
685+
}
686+
687+
return nil;
664688
}
665689

666690
RCT_EXPORT_METHOD(addBreadcrumb : (NSDictionary *)breadcrumb)

0 commit comments

Comments
 (0)