Skip to content

Commit 1cc2a9e

Browse files
authored
Merge 02cbc4b into 27e7514
2 parents 27e7514 + 02cbc4b commit 1cc2a9e

File tree

7 files changed

+159
-65
lines changed

7 files changed

+159
-65
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Fixes
6+
7+
- Add null-handling for parsed DSN in SentryHTTPTransport (#5800)
8+
39
## 8.54.1-alpha.0
410

511
> [!Important]

Sources/Sentry/SentryHttpTransport.m

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ @interface SentryHttpTransport ()
3333
@property (nonatomic, strong) SentryFileManager *fileManager;
3434
@property (nonatomic, strong) id<SentryRequestManager> requestManager;
3535
@property (nonatomic, strong) SentryNSURLRequestBuilder *requestBuilder;
36-
@property (nonatomic, strong) SentryOptions *options;
36+
@property (nonatomic, strong) SentryDsn *dsn;
37+
@property (nonatomic) BOOL sendClientReports;
3738
@property (nonatomic, strong) id<SentryRateLimits> rateLimits;
3839
@property (nonatomic, strong) SentryEnvelopeRateLimit *envelopeRateLimit;
3940
@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueue;
@@ -67,7 +68,8 @@ @interface SentryHttpTransport ()
6768

6869
@implementation SentryHttpTransport
6970

70-
- (id)initWithOptions:(SentryOptions *)options
71+
- (id)initWithDsn:(SentryDsn *)dsn
72+
sendClientReports:(BOOL)sendClientReports
7173
cachedEnvelopeSendDelay:(NSTimeInterval)cachedEnvelopeSendDelay
7274
dateProvider:(id<SentryCurrentDateProvider>)dateProvider
7375
fileManager:(SentryFileManager *)fileManager
@@ -78,7 +80,8 @@ - (id)initWithOptions:(SentryOptions *)options
7880
dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper
7981
{
8082
if (self = [super init]) {
81-
self.options = options;
83+
self.dsn = dsn;
84+
self.sendClientReports = sendClientReports;
8285
_cachedEnvelopeSendDelay = cachedEnvelopeSendDelay;
8386
self.requestManager = requestManager;
8487
self.requestBuilder = requestBuilder;
@@ -162,7 +165,7 @@ - (void)recordLostEvent:(SentryDataCategory)category
162165
reason:(SentryDiscardReason)reason
163166
quantity:(NSUInteger)quantity
164167
{
165-
if (!self.options.sendClientReports) {
168+
if (!self.sendClientReports) {
166169
return;
167170
}
168171

@@ -276,7 +279,7 @@ - (void)envelopeItemDeleted:(SentryEnvelopeItem *)envelopeItem
276279

277280
- (SentryEnvelope *)addClientReportTo:(SentryEnvelope *)envelope
278281
{
279-
if (!self.options.sendClientReports) {
282+
if (!self.sendClientReports) {
280283
return envelope;
281284
}
282285

@@ -357,14 +360,14 @@ - (void)sendAllCachedEnvelopes
357360
// We must set sentAt as close as possible to the transmission of the envelope to Sentry.
358361
rateLimitedEnvelope.header.sentAt = [self.dateProvider date];
359362

360-
NSError *requestError = nil;
363+
NSError *_Nullable requestError = nil;
361364
NSURLRequest *request = [self.requestBuilder createEnvelopeRequest:rateLimitedEnvelope
362-
dsn:self.options.parsedDsn
365+
dsn:self.dsn
363366
didFailWithError:&requestError];
364367

365368
if (nil == request || nil != requestError) {
366369
if (nil != requestError) {
367-
SENTRY_LOG_DEBUG(@"Failed to build request: %@.", requestError);
370+
SENTRY_LOG_FATAL(@"Failed to build request to send envelope: %@.", requestError);
368371
}
369372
[self recordLostEventFor:rateLimitedEnvelope.items];
370373
[self deleteEnvelopeAndSendNext:envelopeFilePath];

Sources/Sentry/SentryTransportFactory.m

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#import "SentryEnvelopeRateLimit.h"
44
#import "SentryHttpDateParser.h"
55
#import "SentryHttpTransport.h"
6+
#import "SentryInternalDefines.h"
7+
#import "SentryLogC.h"
68
#import "SentryNSURLRequestBuilder.h"
79
#import "SentryOptions.h"
810
#import "SentryQueueableRequestManager.h"
@@ -27,34 +29,37 @@ @implementation SentryTransportFactory
2729
sentryFileManager:(SentryFileManager *)sentryFileManager
2830
rateLimits:(id<SentryRateLimits>)rateLimits
2931
{
30-
NSURLSession *session;
31-
32-
if (options.urlSession) {
33-
session = options.urlSession;
34-
} else {
35-
NSURLSessionConfiguration *configuration =
36-
[NSURLSessionConfiguration ephemeralSessionConfiguration];
37-
session = [NSURLSession sessionWithConfiguration:configuration
38-
delegate:options.urlSessionDelegate
39-
delegateQueue:nil];
40-
}
32+
NSMutableArray<id<SentryTransport>> *transports = [NSMutableArray array];
4133

34+
NSURLSession *session = [self getUrlSession:options];
4235
id<SentryRequestManager> requestManager =
4336
[[SentryQueueableRequestManager alloc] initWithSession:session];
44-
4537
SentryEnvelopeRateLimit *envelopeRateLimit =
4638
[[SentryEnvelopeRateLimit alloc] initWithRateLimits:rateLimits];
47-
48-
dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class(
49-
DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_PRIORITY_LOW, 0);
50-
SentryDispatchQueueWrapper *dispatchQueueWrapper =
51-
[[SentryDispatchQueueWrapper alloc] initWithName:"io.sentry.http-transport"
52-
attributes:attributes];
39+
SentryDispatchQueueWrapper *dispatchQueueWrapper = [self createDispatchQueueWrapper];
5340

5441
SentryNSURLRequestBuilder *requestBuilder = [[SentryNSURLRequestBuilder alloc] init];
5542

56-
SentryHttpTransport *httpTransport =
57-
[[SentryHttpTransport alloc] initWithOptions:options
43+
if (options.enableSpotlight) {
44+
SENTRY_LOG_DEBUG(@"Spotlight is enabled, creating Spotlight transport.");
45+
SentrySpotlightTransport *spotlightTransport =
46+
[[SentrySpotlightTransport alloc] initWithOptions:options
47+
requestManager:requestManager
48+
requestBuilder:requestBuilder
49+
dispatchQueueWrapper:dispatchQueueWrapper];
50+
51+
[transports addObject:spotlightTransport];
52+
} else {
53+
SENTRY_LOG_DEBUG(@"Spotlight is disabled in options, not adding Spotlight transport.");
54+
}
55+
56+
if (options.parsedDsn) {
57+
SENTRY_LOG_DEBUG(@"Options contain parsed DSN, creating HTTP transport.");
58+
SentryDsn *_Nonnull dsn = SENTRY_UNWRAP_NULLABLE(SentryDsn, options.parsedDsn);
59+
60+
SentryHttpTransport *httpTransport =
61+
[[SentryHttpTransport alloc] initWithDsn:dsn
62+
sendClientReports:options.sendClientReports
5863
cachedEnvelopeSendDelay:0.1
5964
dateProvider:dateProvider
6065
fileManager:sentryFileManager
@@ -64,18 +69,39 @@ @implementation SentryTransportFactory
6469
envelopeRateLimit:envelopeRateLimit
6570
dispatchQueueWrapper:dispatchQueueWrapper];
6671

67-
if (options.enableSpotlight) {
68-
SentrySpotlightTransport *spotlightTransport =
69-
[[SentrySpotlightTransport alloc] initWithOptions:options
70-
requestManager:requestManager
71-
requestBuilder:requestBuilder
72-
dispatchQueueWrapper:dispatchQueueWrapper];
73-
return @[ httpTransport, spotlightTransport ];
72+
[transports addObject:httpTransport];
7473
} else {
75-
return @[ httpTransport ];
74+
SENTRY_LOG_WARN(
75+
@"Failed to create HTTP transport because the SentryOptions does not contain "
76+
@"a parsed DSN.");
7677
}
78+
79+
return transports;
7780
}
7881

82+
+ (NSURLSession *)getUrlSession:(SentryOptions *_Nonnull)options
83+
{
84+
if (options.urlSession) {
85+
SENTRY_LOG_DEBUG(@"Using URL session provided in SDK options for HTTP transport.");
86+
return SENTRY_UNWRAP_NULLABLE(NSURLSession, options.urlSession);
87+
}
88+
89+
NSURLSessionConfiguration *configuration =
90+
[NSURLSessionConfiguration ephemeralSessionConfiguration];
91+
return [NSURLSession sessionWithConfiguration:configuration
92+
delegate:options.urlSessionDelegate
93+
delegateQueue:nil];
94+
}
95+
96+
+ (SentryDispatchQueueWrapper *)createDispatchQueueWrapper
97+
{
98+
dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class(
99+
DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_PRIORITY_LOW, 0);
100+
SentryDispatchQueueWrapper *dispatchQueueWrapper =
101+
[[SentryDispatchQueueWrapper alloc] initWithName:"io.sentry.http-transport"
102+
attributes:attributes];
103+
return dispatchQueueWrapper;
104+
}
79105
@end
80106

81107
NS_ASSUME_NONNULL_END

Sources/Sentry/include/SentryHttpTransport.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
@class SentryDispatchQueueWrapper;
99
@class SentryNSURLRequestBuilder;
10-
@class SentryOptions;
10+
@class SentryDsn;
1111
@protocol SentryCurrentDateProvider;
1212

1313
NS_ASSUME_NONNULL_BEGIN
@@ -16,7 +16,8 @@ NS_ASSUME_NONNULL_BEGIN
1616
: NSObject <SentryTransport, SentryEnvelopeRateLimitDelegate, SentryFileManagerDelegate>
1717
SENTRY_NO_INIT
1818

19-
- (id)initWithOptions:(SentryOptions *)options
19+
- (id)initWithDsn:(SentryDsn *)dsn
20+
sendClientReports:(BOOL)sendClientReports
2021
cachedEnvelopeSendDelay:(NSTimeInterval)cachedEnvelopeSendDelay
2122
dateProvider:(id<SentryCurrentDateProvider>)dateProvider
2223
fileManager:(SentryFileManager *)fileManager

Tests/SentryTests/Networking/SentryHttpTransportFlushIntegrationTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ final class SentryHttpTransportFlushIntegrationTests: XCTestCase {
164164
let dispatchQueueWrapper = SentryDispatchQueueWrapper()
165165

166166
return (SentryHttpTransport(
167-
options: options,
167+
dsn: try XCTUnwrap(options.parsedDsn),
168+
sendClientReports: options.sendClientReports,
168169
cachedEnvelopeSendDelay: 0.0,
169170
dateProvider: SentryDefaultCurrentDateProvider(),
170171
fileManager: fileManager,

Tests/SentryTests/Networking/SentryHttpTransportTests.swift

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,10 @@ class SentryHttpTransportTests: XCTestCase {
136136
func getSut(
137137
fileManager: SentryFileManager? = nil,
138138
dispatchQueueWrapper: SentryDispatchQueueWrapper? = nil
139-
) -> SentryHttpTransport {
139+
) throws -> SentryHttpTransport {
140140
return SentryHttpTransport(
141-
options: options,
141+
dsn: try XCTUnwrap(options.parsedDsn),
142+
sendClientReports: options.sendClientReports,
142143
cachedEnvelopeSendDelay: 0.0,
143144
dateProvider: currentDateProvider,
144145
fileManager: fileManager ?? self.fileManager,
@@ -163,13 +164,13 @@ class SentryHttpTransportTests: XCTestCase {
163164
private var fixture: Fixture!
164165
private var sut: SentryHttpTransport!
165166

166-
override func setUp() {
167+
override func setUpWithError() throws {
167168
super.setUp()
168169
fixture = Fixture()
169170
fixture.fileManager.deleteAllEnvelopes()
170171
fixture.requestManager.returnResponse(response: HTTPURLResponse())
171172

172-
sut = fixture.getSut()
173+
sut = try fixture.getSut()
173174
}
174175

175176
override func tearDown() {
@@ -179,14 +180,14 @@ class SentryHttpTransportTests: XCTestCase {
179180
clearTestState()
180181
}
181182

182-
func testInitSendsCachedEnvelopes() {
183+
func testInitSendsCachedEnvelopes() throws {
183184
givenNoInternetConnection()
184185
sendEventAsync()
185186
assertEnvelopesStored(envelopeCount: 1)
186187

187188
waitForAllRequests()
188189
givenOkResponse()
189-
let sut = fixture.getSut()
190+
let sut = try fixture.getSut()
190191
XCTAssertNotNil(sut)
191192
waitForAllRequests()
192193

@@ -520,8 +521,8 @@ class SentryHttpTransportTests: XCTestCase {
520521
func testFailureToStoreEvenlopeEventStillSendsRequest() throws {
521522
let fileManger = try TestFileManager(options: fixture.options)
522523
fileManger.storeEnvelopePathNil = true // Failure to store envelope returns nil path
523-
let sut = fixture.getSut(fileManager: fileManger)
524-
524+
let sut = try fixture.getSut(fileManager: fileManger)
525+
525526
sut.send(envelope: fixture.eventEnvelope)
526527

527528
XCTAssertEqual(fileManger.storeEnvelopeInvocations.count, 1)
@@ -750,13 +751,13 @@ class SentryHttpTransportTests: XCTestCase {
750751
fixture.dispatchQueueWrapper.dispatchAfterExecutesBlock = false
751752

752753
// Interact with sut in extra function so ARC deallocates it
753-
func getSut() {
754-
let sut = fixture.getSut()
754+
func getSut() throws {
755+
let sut = try fixture.getSut()
755756
sut.send(envelope: fixture.eventEnvelope)
756757
waitForAllRequests()
757758
}
758-
getSut()
759-
759+
try getSut()
760+
760761
for dispatchAfterBlock in fixture.dispatchQueueWrapper.dispatchAfterInvocations.invocations {
761762
dispatchAfterBlock.block()
762763
}
@@ -841,21 +842,23 @@ class SentryHttpTransportTests: XCTestCase {
841842
assertClientReportStoredInMemory()
842843
}
843844

844-
func testSendClientReportsDisabled_DoesNotRecordLostEvents() {
845+
func testSendClientReportsDisabled_DoesNotRecordLostEvents() throws {
845846
fixture.options.sendClientReports = false
847+
sut = try fixture.getSut()
846848
givenErrorResponse()
847849

848850
sendEvent()
849851

850852
assertClientReportNotStoredInMemory()
851853
}
852854

853-
func testSendClientReportsDisabled_DoesSendClientReport() {
855+
func testSendClientReportsDisabled_DoesSendClientReport() throws {
854856
givenErrorResponse()
855857
sendEvent()
856858

857859
givenOkResponse()
858860
fixture.options.sendClientReports = false
861+
sut = try fixture.getSut()
859862
sendEvent()
860863

861864
assertEventIsSentAsEnvelope()
@@ -917,18 +920,18 @@ class SentryHttpTransportTests: XCTestCase {
917920
XCTAssertEqual(2, fixture.requestManager.requests.count)
918921
}
919922

920-
func testDealloc_StopsReachabilityMonitoring() {
921-
func deallocSut() {
922-
_ = fixture.getSut()
923+
func testDealloc_StopsReachabilityMonitoring() throws {
924+
func deallocSut() throws {
925+
_ = try fixture.getSut()
923926
}
924-
deallocSut()
927+
try deallocSut()
925928

926929
XCTAssertEqual(1, fixture.reachability.stopMonitoringInvocations.count)
927930
}
928931

929-
func testDealloc_TriggerNetworkReachable_NoCrash() {
930-
_ = fixture.getSut()
931-
932+
func testDealloc_TriggerNetworkReachable_NoCrash() throws {
933+
_ = try fixture.getSut()
934+
932935
fixture.reachability.triggerNetworkReachable()
933936
}
934937
#endif // !os(watchOS)

0 commit comments

Comments
 (0)