Skip to content

Commit 9efd563

Browse files
committed
Merge branch 'main' into enha/flutter-min-version-test
2 parents 893961e + 5170678 commit 9efd563

32 files changed

+276
-293
lines changed

CHANGELOG.md

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

3+
## Unreleased
4+
5+
### Dependencies
6+
7+
- Bump Android SDK from v6.6.0 to v6.7.0 ([#1105](https://github.com/getsentry/sentry-dart/pull/1105))
8+
- [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#670)
9+
- [diff](https://github.com/getsentry/sentry-java/compare/6.6.0...6.7.0)
10+
- Bump Cocoa SDK from v7.30.0 to v7.30.1 ([#1104](https://github.com/getsentry/sentry-dart/pull/1104))
11+
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/master/CHANGELOG.md#7301)
12+
- [diff](https://github.com/getsentry/sentry-cocoa/compare/7.30.0...7.30.1)
13+
14+
## 6.14.0
15+
16+
### Features
17+
18+
- Capture response information in `SentryHttpClient` ([#1095](https://github.com/getsentry/sentry-dart/pull/1095))
19+
20+
### Changes
21+
22+
- Remove experimental `SentryResponse` fields: `url`, `body`, `redirected`, `status` ([#1095](https://github.com/getsentry/sentry-dart/pull/1095))
23+
- `SentryHttpClient` request body capture checks default PII capture setting, same as the DIO integration ([#1095](https://github.com/getsentry/sentry-dart/pull/1095))
24+
25+
### Dependencies
26+
27+
- Bump Android SDK from v6.5.0 to v6.6.0 ([#1090](https://github.com/getsentry/sentry-dart/pull/1090))
28+
- [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#660)
29+
- [diff](https://github.com/getsentry/sentry-java/compare/6.5.0...6.6.0)
30+
- Bump Cocoa SDK from v7.28.0 to v7.30.0 ([#1089](https://github.com/getsentry/sentry-dart/pull/1089), [#1101](https://github.com/getsentry/sentry-dart/pull/1101))
31+
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/master/CHANGELOG.md#7300)
32+
- [diff](https://github.com/getsentry/sentry-cocoa/compare/7.28.0...7.30.0)
33+
334
## 6.13.1
435

536
### Fixes

dart/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Sentry SDK for Dart
1010

1111
| package | build | pub | likes | popularity | pub points |
1212
| ------- | ------- | ------- | ------- | ------- | ------- |
13-
| sentry | [![build](https://github.com/getsentry/sentry-dart/workflows/sentry-dart/badge.svg?branch=main)](https://github.com/getsentry/sentry-dart/actions?query=workflow%3Asentry-dart) | [![pub package](https://img.shields.io/pub/v/sentry.svg)](https://pub.dev/packages/sentry) | [![likes](https://badges.bar/sentry/likes)](https://pub.dev/packages/sentry/score) | [![popularity](https://badges.bar/sentry/popularity)](https://pub.dev/packages/sentry/score) | [![pub points](https://badges.bar/sentry/pub%20points)](https://pub.dev/packages/sentry/score)
13+
| sentry | [![build](https://github.com/getsentry/sentry-dart/workflows/sentry-dart/badge.svg?branch=main)](https://github.com/getsentry/sentry-dart/actions?query=workflow%3Asentry-dart) | [![pub package](https://img.shields.io/pub/v/sentry.svg)](https://pub.dev/packages/sentry) | [![likes](https://img.shields.io/pub/likes/sentry)](https://pub.dev/packages/sentry/score) | [![popularity](https://img.shields.io/pub/popularity/sentry)](https://img.shields.io/pub/sentry) | [![pub points](https://img.shields.io/pub/points/sentry)](https://pub.dev/packages/sentry/score)
1414

1515
Pure Dart SDK used by any Dart application like AngularDart, CLI and Server.
1616

dart/lib/src/http_client/failed_request_client.dart

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@ class FailedRequestClient extends BaseClient {
7777
final Client _client;
7878
final Hub _hub;
7979

80-
/// Configures wether to record exceptions for failed requests.
80+
/// Configures whether to record exceptions for failed requests.
8181
/// Examples for captures exceptions are:
8282
/// - In an browser environment this can be requests which fail because of CORS.
8383
/// - In an mobile or desktop application this can be requests which failed
8484
/// because the connection was interrupted.
8585
final bool captureFailedRequests;
8686

8787
/// Configures up to which size request bodies should be included in events.
88-
/// This does not change wether an event is captured.
88+
/// This does not change whether an event is captured.
8989
final MaxRequestBodySize maxRequestBodySize;
9090

9191
/// Describes which HTTP status codes should be considered as a failed
@@ -101,12 +101,13 @@ class FailedRequestClient extends BaseClient {
101101
int? statusCode;
102102
Object? exception;
103103
StackTrace? stackTrace;
104+
StreamedResponse? response;
104105

105106
final stopwatch = Stopwatch();
106107
stopwatch.start();
107108

108109
try {
109-
final response = await _client.send(request);
110+
response = await _client.send(request);
110111
statusCode = response.statusCode;
111112
return response;
112113
} catch (e, st) {
@@ -118,25 +119,25 @@ class FailedRequestClient extends BaseClient {
118119

119120
// If captureFailedRequests is true, there statusCode is null.
120121
// So just one of these blocks can be called.
121-
122+
var capture = false;
123+
String? reason;
122124
if (captureFailedRequests && exception != null) {
123-
await _captureEvent(
124-
exception: exception,
125-
stackTrace: stackTrace,
126-
request: request,
127-
requestDuration: stopwatch.elapsed,
128-
);
125+
capture = true;
129126
} else if (failedRequestStatusCodes.containsStatusCode(statusCode)) {
130-
final message =
131-
'Event was captured because the request status code was $statusCode';
132-
final httpException = SentryHttpClientError(message);
133-
134127
// Capture an exception if the status code is considered bad
128+
capture = true;
129+
reason =
130+
'Event was captured because the request status code was $statusCode';
131+
exception ??= SentryHttpClientError(reason);
132+
}
133+
if (capture) {
135134
await _captureEvent(
136-
exception: exception ?? httpException,
135+
exception: exception,
136+
stackTrace: stackTrace,
137137
request: request,
138-
reason: message,
139138
requestDuration: stopwatch.elapsed,
139+
response: response,
140+
reason: reason,
140141
);
141142
}
142143
}
@@ -152,6 +153,7 @@ class FailedRequestClient extends BaseClient {
152153
String? reason,
153154
required Duration requestDuration,
154155
required BaseRequest request,
156+
required StreamedResponse? response,
155157
}) async {
156158
// As far as I can tell there's no way to get the uri without the query part
157159
// so we replace it with an empty string.
@@ -164,8 +166,7 @@ class FailedRequestClient extends BaseClient {
164166
headers: sendDefaultPii ? request.headers : null,
165167
url: urlWithoutQuery,
166168
queryString: query,
167-
cookies: sendDefaultPii ? request.headers['Cookie'] : null,
168-
data: _getDataFromRequest(request),
169+
data: sendDefaultPii ? _getDataFromRequest(request) : null,
169170
// ignore: deprecated_member_use_from_same_package
170171
other: {
171172
'content_length': request.contentLength.toString(),
@@ -183,6 +184,15 @@ class FailedRequestClient extends BaseClient {
183184
throwable: throwableMechanism,
184185
request: sentryRequest,
185186
);
187+
188+
if (response != null) {
189+
event.contexts.response = SentryResponse(
190+
headers: sendDefaultPii ? response.headers : null,
191+
bodySize: response.contentLength,
192+
statusCode: response.statusCode,
193+
);
194+
}
195+
186196
await _hub.captureEvent(event, stackTrace: stackTrace);
187197
}
188198

dart/lib/src/platform_checker.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class PlatformChecker {
3333
: 'profile';
3434
}
3535

36-
/// Indicates wether a native integration is available.
36+
/// Indicates whether a native integration is available.
3737
bool get hasNativeIntegration {
3838
if (isWeb) {
3939
return false;

dart/lib/src/protocol/max_body_size.dart

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,16 @@ enum MaxRequestBodySize {
2323

2424
extension MaxRequestBodySizeX on MaxRequestBodySize {
2525
bool shouldAddBody(int contentLength) {
26-
if (this == MaxRequestBodySize.never) {
27-
return false;
28-
}
29-
if (this == MaxRequestBodySize.always) {
30-
return true;
31-
}
32-
if (this == MaxRequestBodySize.medium && contentLength <= _mediumSize) {
33-
return true;
34-
}
35-
36-
if (this == MaxRequestBodySize.small && contentLength <= _smallSize) {
37-
return true;
26+
switch (this) {
27+
case MaxRequestBodySize.never:
28+
break;
29+
case MaxRequestBodySize.small:
30+
return contentLength <= _smallSize;
31+
case MaxRequestBodySize.medium:
32+
return contentLength <= _mediumSize;
33+
case MaxRequestBodySize.always:
34+
return true;
35+
// No default here to get a warning when a new enum value is added.
3836
}
3937
return false;
4038
}
@@ -61,18 +59,16 @@ enum MaxResponseBodySize {
6159

6260
extension MaxResponseBodySizeX on MaxResponseBodySize {
6361
bool shouldAddBody(int contentLength) {
64-
if (this == MaxResponseBodySize.never) {
65-
return false;
66-
}
67-
if (this == MaxResponseBodySize.always) {
68-
return true;
69-
}
70-
if (this == MaxResponseBodySize.medium && contentLength <= _mediumSize) {
71-
return true;
72-
}
73-
74-
if (this == MaxResponseBodySize.small && contentLength <= _smallSize) {
75-
return true;
62+
switch (this) {
63+
case MaxResponseBodySize.never:
64+
break;
65+
case MaxResponseBodySize.small:
66+
return contentLength <= _smallSize;
67+
case MaxResponseBodySize.medium:
68+
return contentLength <= _mediumSize;
69+
case MaxResponseBodySize.always:
70+
return true;
71+
// No default here to get a warning when a new enum value is added.
7672
}
7773
return false;
7874
}

dart/lib/src/protocol/sentry_request.dart

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import 'package:meta/meta.dart';
22

3+
import '../utils/iterable_extension.dart';
4+
35
/// The Request interface contains information on a HTTP request related to the event.
46
/// In client SDKs, this can be an outgoing request, or the request that rendered the current web page.
57
/// On server SDKs, this could be the incoming web request that is being handled.
@@ -63,14 +65,19 @@ class SentryRequest {
6365
this.url,
6466
this.method,
6567
this.queryString,
66-
this.cookies,
68+
String? cookies,
6769
this.fragment,
6870
dynamic data,
6971
Map<String, String>? headers,
7072
Map<String, String>? env,
7173
@Deprecated('Will be removed in v7.') Map<String, String>? other,
7274
}) : _data = data,
7375
_headers = headers != null ? Map.from(headers) : null,
76+
// Look for a 'Set-Cookie' header (case insensitive) if not given.
77+
cookies = cookies ??
78+
headers?.entries
79+
.firstWhereOrNull((e) => e.key.toLowerCase() == 'cookie')
80+
?.value,
7481
_env = env != null ? Map.from(env) : null,
7582
_other = other != null ? Map.from(other) : null;
7683

@@ -82,10 +89,10 @@ class SentryRequest {
8289
queryString: json['query_string'],
8390
cookies: json['cookies'],
8491
data: json['data'],
85-
headers: json['headers'],
86-
env: json['env'],
92+
headers: json.containsKey('headers') ? Map.from(json['headers']) : null,
93+
env: json.containsKey('env') ? Map.from(json['env']) : null,
8794
// ignore: deprecated_member_use_from_same_package
88-
other: json['other'],
95+
other: json.containsKey('other') ? Map.from(json['other']) : null,
8996
fragment: json['fragment'],
9097
);
9198
}
Lines changed: 28 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:meta/meta.dart';
22
import 'contexts.dart';
3+
import '../utils/iterable_extension.dart';
34

45
/// The response interface contains information on a HTTP request related to the event.
56
/// This is an experimental feature. It might be removed at any time.
@@ -9,24 +10,13 @@ class SentryResponse {
910
/// The tpye of this class in the [Contexts] field
1011
static const String type = 'response';
1112

12-
/// The URL of the response if available.
13-
/// This might be the redirected URL
14-
final String? url;
15-
16-
/// Indicates whether or not the response is the result of a redirect
17-
/// (that is, its URL list has more than one entry).
18-
final bool? redirected;
19-
20-
/// The body of the response
21-
final Object? body;
13+
/// The size of the response body.
14+
final int? bodySize;
2215

2316
/// The HTTP status code of the response.
2417
/// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
2518
final int? statusCode;
2619

27-
/// The status message for the corresponding [statusCode]
28-
final String? status;
29-
3020
/// An immutable dictionary of submitted headers.
3121
/// If a header appears multiple times it,
3222
/// needs to be merged according to the HTTP standard for header merging.
@@ -35,73 +25,57 @@ class SentryResponse {
3525

3626
final Map<String, String>? _headers;
3727

38-
Map<String, String> get other => Map.unmodifiable(_other ?? const {});
28+
/// Cookie key-value pairs as string.
29+
final String? cookies;
3930

40-
final Map<String, String>? _other;
41-
42-
SentryResponse({
43-
this.url,
44-
this.body,
45-
this.redirected,
46-
this.statusCode,
47-
this.status,
48-
Map<String, String>? headers,
49-
Map<String, String>? other,
50-
}) : _headers = headers != null ? Map.from(headers) : null,
51-
_other = other != null ? Map.from(other) : null;
31+
SentryResponse(
32+
{this.bodySize,
33+
this.statusCode,
34+
Map<String, String>? headers,
35+
String? cookies})
36+
: _headers = headers != null ? Map.from(headers) : null,
37+
// Look for a 'Set-Cookie' header (case insensitive) if not given.
38+
cookies = cookies ??
39+
headers?.entries
40+
.firstWhereOrNull((e) => e.key.toLowerCase() == 'set-cookie')
41+
?.value;
5242

5343
/// Deserializes a [SentryResponse] from JSON [Map].
5444
factory SentryResponse.fromJson(Map<String, dynamic> json) {
5545
return SentryResponse(
56-
url: json['url'],
57-
headers: json['headers'],
58-
other: json['other'],
59-
body: json['body'],
60-
statusCode: json['status_code'],
61-
status: json['status'],
62-
redirected: json['redirected'],
63-
);
46+
headers: json.containsKey('headers') ? Map.from(json['headers']) : null,
47+
cookies: json['cookies'],
48+
bodySize: json['body_size'],
49+
statusCode: json['status_code']);
6450
}
6551

6652
/// Produces a [Map] that can be serialized to JSON.
6753
Map<String, dynamic> toJson() {
6854
return <String, dynamic>{
69-
if (url != null) 'url': url,
7055
if (headers.isNotEmpty) 'headers': headers,
71-
if (other.isNotEmpty) 'other': other,
72-
if (redirected != null) 'redirected': redirected,
73-
if (body != null) 'body': body,
74-
if (status != null) 'status': status,
56+
if (cookies != null) 'cookies': cookies,
57+
if (bodySize != null) 'body_size': bodySize,
7558
if (statusCode != null) 'status_code': statusCode,
7659
};
7760
}
7861

7962
SentryResponse copyWith({
80-
String? url,
81-
bool? redirected,
8263
int? statusCode,
83-
String? status,
84-
Object? body,
64+
int? bodySize,
8565
Map<String, String>? headers,
86-
Map<String, String>? other,
66+
String? cookies,
8767
}) =>
8868
SentryResponse(
89-
url: url ?? this.url,
9069
headers: headers ?? _headers,
91-
redirected: redirected ?? this.redirected,
92-
other: other ?? _other,
93-
body: body ?? this.body,
94-
status: status ?? this.status,
70+
cookies: cookies ?? this.cookies,
71+
bodySize: bodySize ?? this.bodySize,
9572
statusCode: statusCode ?? this.statusCode,
9673
);
9774

9875
SentryResponse clone() => SentryResponse(
99-
body: body,
76+
bodySize: bodySize,
10077
headers: headers,
101-
other: other,
102-
redirected: redirected,
103-
status: status,
78+
cookies: cookies,
10479
statusCode: statusCode,
105-
url: url,
10680
);
10781
}

0 commit comments

Comments
 (0)