Skip to content

Commit 388f479

Browse files
authored
Merge c408522 into 82f60cf
2 parents 82f60cf + c408522 commit 388f479

File tree

7 files changed

+97
-46
lines changed

7 files changed

+97
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Fix Infinite Session Replay Processing Loop (#5765)
99
- Fix memory leak in SessionReplayIntegration (#5770)
1010
- Fix reporting of energy used while profiling (#5768)
11+
- Add null-handling for parsed DSN in SentryHTTPTransport (#5800)
1112

1213
### Internal
1314

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: 19 additions & 9 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,6 +29,13 @@ @implementation SentryTransportFactory
2729
sentryFileManager:(SentryFileManager *)sentryFileManager
2830
rateLimits:(id<SentryRateLimits>)rateLimits
2931
{
32+
if (!options.parsedDsn) {
33+
SENTRY_LOG_FATAL(@"Failed to create transports because the SentryOptions does not contain "
34+
@"a parsed DSN.");
35+
return @[];
36+
}
37+
SentryDsn *_Nonnull dsn = SENTRY_UNWRAP_NULLABLE(SentryDsn, options.parsedDsn);
38+
3039
NSURLSession *session;
3140

3241
if (options.urlSession) {
@@ -54,15 +63,16 @@ @implementation SentryTransportFactory
5463
SentryNSURLRequestBuilder *requestBuilder = [[SentryNSURLRequestBuilder alloc] init];
5564

5665
SentryHttpTransport *httpTransport =
57-
[[SentryHttpTransport alloc] initWithOptions:options
58-
cachedEnvelopeSendDelay:0.1
59-
dateProvider:dateProvider
60-
fileManager:sentryFileManager
61-
requestManager:requestManager
62-
requestBuilder:requestBuilder
63-
rateLimits:rateLimits
64-
envelopeRateLimit:envelopeRateLimit
65-
dispatchQueueWrapper:dispatchQueueWrapper];
66+
[[SentryHttpTransport alloc] initWithDsn:dsn
67+
sendClientReports:options.sendClientReports
68+
cachedEnvelopeSendDelay:0.1
69+
dateProvider:dateProvider
70+
fileManager:sentryFileManager
71+
requestManager:requestManager
72+
requestBuilder:requestBuilder
73+
rateLimits:rateLimits
74+
envelopeRateLimit:envelopeRateLimit
75+
dispatchQueueWrapper:dispatchQueueWrapper];
6676

6777
if (options.enableSpotlight) {
6878
SentrySpotlightTransport *spotlightTransport =

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)

Tests/SentryTests/Networking/SentryTransportFactoryTests.swift

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import Sentry
33
import XCTest
44

55
class SentryTransportFactoryTests: XCTestCase {
6-
76
private static let dsnAsString = TestConstants.dsnAsString(username: "SentryTransportFactoryTests")
87

98
func testIntegration_UrlSessionDelegate_PassedToRequestManager() throws {
9+
// -- Arrange --
1010
let urlSessionDelegateSpy = UrlSessionDelegateSpy()
1111

1212
let expect = expectation(description: "UrlSession Delegate of Options called in RequestManager")
@@ -19,6 +19,8 @@ class SentryTransportFactoryTests: XCTestCase {
1919
options.urlSessionDelegate = urlSessionDelegateSpy
2020

2121
let fileManager = try! SentryFileManager(options: options, dispatchQueueWrapper: TestSentryDispatchQueueWrapper())
22+
23+
// -- Act --
2224
let transports = TransportInitializer.initTransports(
2325
options,
2426
dateProvider: SentryDependencyContainer.sharedInstance().dateProvider,
@@ -32,11 +34,13 @@ class SentryTransportFactoryTests: XCTestCase {
3234
let request = URLRequest(url: imgUrl)
3335

3436
requestManager.add(request) { _, _ in /* We don't care about the result */ }
37+
38+
// -- Assert --
3539
wait(for: [expect], timeout: 10)
3640
}
3741

3842
func testShouldReturnTransports_WhenURLSessionPassed() throws {
39-
43+
// -- Arrange --
4044
let urlSessionDelegateSpy = UrlSessionDelegateSpy()
4145
let expect = expectation(description: "UrlSession Delegate of Options called in RequestManager")
4246

@@ -46,9 +50,12 @@ class SentryTransportFactoryTests: XCTestCase {
4650
}
4751

4852
let options = Options()
53+
options.dsn = SentryTransportFactoryTests.dsnAsString
4954
options.urlSession = sessionConfiguration
5055

5156
let fileManager = try! SentryFileManager(options: options, dispatchQueueWrapper: TestSentryDispatchQueueWrapper())
57+
58+
// -- Act --
5259
let transports = TransportInitializer.initTransports(
5360
options,
5461
dateProvider: SentryDependencyContainer.sharedInstance().dateProvider,
@@ -63,35 +70,60 @@ class SentryTransportFactoryTests: XCTestCase {
6370
let request = URLRequest(url: imgUrl)
6471

6572
requestManager.add(request) { _, _ in /* We don't care about the result */ }
73+
74+
// -- Assert --
6675
wait(for: [expect], timeout: 10)
6776

6877
}
6978

7079
func testShouldReturnTwoTransports_WhenSpotlightEnabled() throws {
80+
// -- Arrange --
7181
let options = Options()
82+
options.dsn = SentryTransportFactoryTests.dsnAsString
7283
options.enableSpotlight = true
84+
85+
// -- Act --
7386
let transports = TransportInitializer.initTransports(
7487
options,
7588
dateProvider: SentryDependencyContainer.sharedInstance().dateProvider,
7689
sentryFileManager: try SentryFileManager(options: options),
7790
rateLimits: rateLimiting()
7891
)
79-
92+
93+
// -- Assert --
94+
XCTAssertEqual(transports.count, 2)
8095
XCTAssert(transports.contains {
8196
$0.isKind(of: SentrySpotlightTransport.self)
8297
})
83-
8498
XCTAssert(transports.contains {
8599
$0.isKind(of: SentryHttpTransport.self)
86100
})
87101
}
88102

103+
func testInitTransports_whenOptionsParsedDsnNil_shouldReturnEmptyTransports() throws {
104+
// -- Arrange --
105+
let options = Options()
106+
options.dsn = nil
107+
108+
// -- Act --
109+
let transports = TransportInitializer.initTransports(
110+
options,
111+
dateProvider: SentryDependencyContainer.sharedInstance().dateProvider,
112+
sentryFileManager: try SentryFileManager(options: options),
113+
rateLimits: rateLimiting()
114+
)
115+
116+
// -- Assert --
117+
XCTAssertEqual(transports.count, 0)
118+
}
119+
120+
// MARK: - Helpers
121+
89122
private func rateLimiting() -> RateLimits {
90123
let dateProvider = TestCurrentDateProvider()
91124
let retryAfterHeaderParser = RetryAfterHeaderParser(httpDateParser: HttpDateParser(), currentDateProvider: dateProvider)
92125
let rateLimitParser = RateLimitParser(currentDateProvider: dateProvider)
93126

94127
return DefaultRateLimits(retryAfterHeaderParser: retryAfterHeaderParser, andRateLimitParser: rateLimitParser, currentDateProvider: dateProvider)
95128
}
96-
97129
}

0 commit comments

Comments
 (0)