-
-
Notifications
You must be signed in to change notification settings - Fork 409
HTTP Client errors #2308
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
HTTP Client errors #2308
Changes from 6 commits
cb20a7a
068b12d
a04d660
db88adc
1fc2ad4
4bf027c
0587c63
e25e337
faf2672
e83e136
f747af3
6b9b470
40663bb
15914c5
cd34219
42a9ca3
669ebea
0e6f89e
d07ea54
a771f56
f3715cf
4577ab4
6477646
88a0351
7b81bc5
cdc235f
f83aef9
e4e7cb3
048259e
4a5f115
0dc9192
96e48cb
57053ee
3eac0cb
769e4f1
b23c8c9
0beee09
8dd96c6
44134f5
9845b6b
3fae835
0720ab2
1d862a0
f281352
c598b48
fae4a2f
149ffe2
980704f
8082095
8ae6af6
997be6a
00c6d3b
371cbe2
4323730
4a84c75
57a92f8
67272cc
419b0f7
fa66e02
adfcf51
5b65bc9
fa44107
1fcc0de
25a9c7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,19 @@ | ||
| #import "SentryNetworkTracker.h" | ||
| #import "SentryBaggage.h" | ||
| #import "SentryBreadcrumb.h" | ||
| #import "SentryClient+Private.h" | ||
| #import "SentryEvent.h" | ||
| #import "SentryException.h" | ||
| #import "SentryHub+Private.h" | ||
| #import "SentryLog.h" | ||
| #import "SentryMechanism.h" | ||
| #import "SentryRequest.h" | ||
| #import "SentrySDK+Private.h" | ||
| #import "SentryScope+Private.h" | ||
| #import "SentrySerialization.h" | ||
| #import "SentryStacktrace.h" | ||
| #import "SentryThread.h" | ||
| #import "SentryThreadInspector.h" | ||
| #import "SentryTraceContext.h" | ||
| #import "SentryTraceHeader.h" | ||
| #import "SentryTracer.h" | ||
|
|
@@ -16,6 +24,7 @@ | |
|
|
||
| @property (nonatomic, assign) BOOL isNetworkTrackingEnabled; | ||
| @property (nonatomic, assign) BOOL isNetworkBreadcrumbEnabled; | ||
| @property (nonatomic, assign) BOOL isCaptureFailedRequests; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For me, its a bit confusing that this SDK has some properties from the options, but some properties are accessed directly from the options, such as
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO we should only use options, then we would only need a SentryOption property, but I dont know if there is a reason behind this.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure. I would vote passing the values of the options to the constructor and not accessing them via
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something for @philipphofmann
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree to avoid 'SentrySDK.options' but rather have an options parameter in the constructor. Instead of having multiples parameters.
marandaneto marked this conversation as resolved.
Outdated
|
||
|
|
||
| @end | ||
|
|
||
|
|
@@ -34,6 +43,7 @@ - (instancetype)init | |
| if (self = [super init]) { | ||
| _isNetworkTrackingEnabled = NO; | ||
| _isNetworkBreadcrumbEnabled = NO; | ||
| _isCaptureFailedRequests = NO; | ||
| } | ||
| return self; | ||
| } | ||
|
|
@@ -52,11 +62,19 @@ - (void)enableNetworkBreadcrumbs | |
| } | ||
| } | ||
|
|
||
| - (void)enableCaptureFailedRequests | ||
| { | ||
| @synchronized(self) { | ||
| _isCaptureFailedRequests = YES; | ||
| } | ||
| } | ||
|
|
||
| - (void)disable | ||
| { | ||
| @synchronized(self) { | ||
| _isNetworkBreadcrumbEnabled = NO; | ||
| _isNetworkTrackingEnabled = NO; | ||
| _isCaptureFailedRequests = NO; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -206,7 +224,8 @@ - (void)urlSessionTaskResume:(NSURLSessionTask *)sessionTask | |
|
|
||
| - (void)urlSessionTask:(NSURLSessionTask *)sessionTask setState:(NSURLSessionTaskState)newState | ||
| { | ||
| if (!self.isNetworkTrackingEnabled && !self.isNetworkBreadcrumbEnabled) { | ||
| if (!self.isNetworkTrackingEnabled && !self.isNetworkBreadcrumbEnabled | ||
| && !self.isCaptureFailedRequests) { | ||
| return; | ||
| } | ||
|
|
||
|
|
@@ -239,6 +258,8 @@ - (void)urlSessionTask:(NSURLSessionTask *)sessionTask setState:(NSURLSessionTas | |
| } | ||
|
|
||
| if (sessionTask.state == NSURLSessionTaskStateRunning) { | ||
| [self captureEvent:sessionTask]; | ||
|
|
||
| [self addBreadcrumbForSessionTask:sessionTask]; | ||
|
|
||
| NSInteger responseStatusCode = [self urlResponseStatusCode:sessionTask.response]; | ||
|
|
@@ -265,6 +286,88 @@ - (void)urlSessionTask:(NSURLSessionTask *)sessionTask setState:(NSURLSessionTas | |
| SENTRY_LOG_DEBUG(@"SentryNetworkTracker finished HTTP span for sessionTask"); | ||
| } | ||
|
|
||
| - (void)captureEvent:(NSURLSessionTask *)sessionTask | ||
|
marandaneto marked this conversation as resolved.
Outdated
|
||
| { | ||
| NSInteger responseStatusCode = [self urlResponseStatusCode:sessionTask.response]; | ||
|
|
||
| // TODO: check the string contains and regex | ||
| if (!self.isCaptureFailedRequests) { | ||
| return; | ||
| } | ||
|
|
||
| // TODO: check the range | ||
| if (responseStatusCode == 201) { | ||
| return; | ||
| } | ||
|
|
||
| NSString *message = [NSString | ||
| stringWithFormat:@"HTTP Client Error with status code: %li", (long)(responseStatusCode)]; | ||
|
|
||
| SentryEvent *event = [[SentryEvent alloc] initWithLevel:kSentryLevelError]; | ||
|
|
||
| SentryThreadInspector *threadInspector = SentrySDK.currentHub.getClient.threadInspector; | ||
|
philipphofmann marked this conversation as resolved.
|
||
| NSArray<SentryThread *> *threads = [threadInspector getCurrentThreadsWithStackTrace]; | ||
|
marandaneto marked this conversation as resolved.
Outdated
|
||
|
|
||
| SentryException *sentryException = [[SentryException alloc] initWithValue:message | ||
| type:@"HTTP-ClientError"]; | ||
| sentryException.mechanism = | ||
| [[SentryMechanism alloc] initWithType:@"SentryNetworkTrackingIntegration"]; | ||
|
marandaneto marked this conversation as resolved.
Outdated
|
||
|
|
||
| if (threads.count > 0) { | ||
|
marandaneto marked this conversation as resolved.
Outdated
|
||
| SentryStacktrace *sentryStacktrace = [threads[0] stacktrace]; | ||
| sentryStacktrace.snapshot = @(YES); | ||
|
|
||
| sentryException.stacktrace = sentryStacktrace; | ||
| // TODO: do I need this? | ||
| // [threads enumerateObjectsUsingBlock:^(SentryThread *_Nonnull obj, NSUInteger idx, | ||
| // BOOL *_Nonnull stop) { obj.current = [NSNumber numberWithBool:idx == 0]; }]; | ||
|
marandaneto marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| SentryRequest *request = [[SentryRequest alloc] init]; | ||
|
|
||
| NSURLRequest *myRequest = (NSURLRequest *)sessionTask.currentRequest; | ||
|
marandaneto marked this conversation as resolved.
Outdated
|
||
|
|
||
| NSURL *url = [[sessionTask currentRequest] URL]; | ||
| request.url = url.absoluteString; | ||
|
|
||
| request.fragment = url.fragment; | ||
| request.queryString = url.query; | ||
| request.method = myRequest.HTTPMethod; | ||
| if (sessionTask.countOfBytesSent != 0) { | ||
|
marandaneto marked this conversation as resolved.
Outdated
|
||
| request.bodySize = [NSNumber numberWithLongLong:sessionTask.countOfBytesSent]; | ||
| } | ||
| if (nil != myRequest.allHTTPHeaderFields) { | ||
| NSDictionary<NSString *, NSString *> *headers = myRequest.allHTTPHeaderFields.copy; | ||
| request.headers = headers; | ||
| request.cookies = headers[@"Cookie"]; | ||
| } | ||
|
|
||
| event.exceptions = @[ sentryException ]; | ||
| event.request = request; | ||
|
|
||
| NSHTTPURLResponse *myResponse = (NSHTTPURLResponse *)sessionTask.response; | ||
|
|
||
| NSMutableDictionary<NSString *, id> *context = [[NSMutableDictionary alloc] init]; | ||
| ; | ||
|
marandaneto marked this conversation as resolved.
Outdated
marandaneto marked this conversation as resolved.
Outdated
|
||
| NSMutableDictionary<NSString *, id> *response = [[NSMutableDictionary alloc] init]; | ||
|
|
||
| [response setValue:[NSNumber numberWithLongLong:responseStatusCode] forKey:@"status_code"]; | ||
| if (nil != myResponse.allHeaderFields) { | ||
| NSDictionary<NSString *, NSString *> *headers = myResponse.allHeaderFields.copy; | ||
| [response setValue:headers forKey:@"headers"]; | ||
| [response setValue:headers[@"Cookie"] forKey:@"cookies"]; | ||
| } | ||
| if (sessionTask.countOfBytesReceived != 0) { | ||
| [response setValue:[NSNumber numberWithLongLong:sessionTask.countOfBytesReceived] | ||
| forKey:@"body_size"]; | ||
| } | ||
|
|
||
| context[@"response"] = response; | ||
|
marandaneto marked this conversation as resolved.
|
||
| event.context = context; | ||
|
|
||
| [SentrySDK captureEvent:event]; | ||
| } | ||
|
|
||
| - (void)addBreadcrumbForSessionTask:(NSURLSessionTask *)sessionTask | ||
| { | ||
| if (!self.isNetworkBreadcrumbEnabled) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.