Skip to content
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

Feature: Add apiTarget and data fields for GraphQL support #1517

Merged
merged 6 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Enhancements

- Add `apiTarget` field to `SentryRequest` and `data` field to `SentryResponse` ([#1517](https://github.com/getsentry/sentry-dart/pull/1517))

### Dependencies

- Bump Android SDK from v6.21.0 to v6.22.0 ([#1512](https://github.com/getsentry/sentry-dart/pull/1512))
Expand Down
18 changes: 16 additions & 2 deletions dart/lib/src/protocol/sentry_request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,20 @@ class SentryRequest {
/// The fragment of the request URL.
final String? fragment;

/// The API target/specification that made the request.
/// Values can be `graphql`, `rest`, etc.
///
/// The data field should contain the request and response bodies based on
/// its target specification.
final String? apiTarget;

SentryRequest({
this.url,
this.method,
this.queryString,
String? cookies,
this.fragment,
this.apiTarget,
dynamic data,
Map<String, String>? headers,
Map<String, String>? env,
Expand All @@ -90,6 +98,7 @@ class SentryRequest {
dynamic data,
Map<String, String>? headers,
Map<String, String>? env,
String? apiTarget,
@Deprecated('Will be removed in v8. Use [data] instead')
Map<String, String>? other,
}) {
Expand All @@ -104,6 +113,7 @@ class SentryRequest {
fragment: uri.fragment,
// ignore: deprecated_member_use_from_same_package
other: other,
apiTarget: apiTarget,
).sanitized();
}

Expand All @@ -120,6 +130,7 @@ class SentryRequest {
// ignore: deprecated_member_use_from_same_package
other: json.containsKey('other') ? Map.from(json['other']) : null,
fragment: json['fragment'],
apiTarget: json['api_target'],
);
}

Expand All @@ -136,6 +147,7 @@ class SentryRequest {
// ignore: deprecated_member_use_from_same_package
if (other.isNotEmpty) 'other': other,
if (fragment != null) 'fragment': fragment,
if (apiTarget != null) 'api_target': apiTarget,
};
}

Expand All @@ -148,9 +160,10 @@ class SentryRequest {
dynamic data,
Map<String, String>? headers,
Map<String, String>? env,
bool removeCookies = false,
String? apiTarget,
@Deprecated('Will be removed in v8. Use [data] instead')
Map<String, String>? other,
bool removeCookies = false,
}) =>
SentryRequest(
url: url ?? this.url,
Expand All @@ -160,8 +173,9 @@ class SentryRequest {
data: data ?? _data,
headers: headers ?? _headers,
env: env ?? _env,
fragment: fragment ?? this.fragment,
apiTarget: apiTarget ?? this.apiTarget,
// ignore: deprecated_member_use_from_same_package
other: other ?? _other,
fragment: fragment,
);
}
36 changes: 30 additions & 6 deletions dart/lib/src/protocol/sentry_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,31 @@ class SentryResponse {
/// Cookie key-value pairs as string.
final String? cookies;

SentryResponse(
{this.bodySize,
this.statusCode,
Map<String, String>? headers,
String? cookies})
: _headers = headers != null ? Map.from(headers) : null,
final Object? _data;

/// Response data in any format that makes sense.
///
/// SDKs should discard large and binary bodies by default.
/// Can be given as a string or structural data of any format.
Object? get data {
final typedData = _data;
if (typedData is List) {
return List.unmodifiable(typedData);
} else if (typedData is Map) {
return Map.unmodifiable(typedData);
}

return _data;
}

SentryResponse({
this.bodySize,
this.statusCode,
Map<String, String>? headers,
String? cookies,
Object? data,
}) : _data = data,
_headers = headers != null ? Map.from(headers) : null,
// Look for a 'Set-Cookie' header (case insensitive) if not given.
cookies = cookies ??
headers?.entries
Expand All @@ -45,6 +64,7 @@ class SentryResponse {
cookies: json['cookies'],
bodySize: json['body_size'],
statusCode: json['status_code'],
data: json['data'],
);
}

Expand All @@ -55,6 +75,7 @@ class SentryResponse {
if (cookies != null) 'cookies': cookies,
if (bodySize != null) 'body_size': bodySize,
if (statusCode != null) 'status_code': statusCode,
if (data != null) 'data': data,
};
}

Expand All @@ -63,18 +84,21 @@ class SentryResponse {
int? bodySize,
Map<String, String>? headers,
String? cookies,
Object? data,
}) =>
SentryResponse(
headers: headers ?? _headers,
cookies: cookies ?? this.cookies,
bodySize: bodySize ?? this.bodySize,
statusCode: statusCode ?? this.statusCode,
data: data ?? this.data,
);

SentryResponse clone() => SentryResponse(
bodySize: bodySize,
headers: headers,
cookies: cookies,
statusCode: statusCode,
data: data,
);
}
2 changes: 2 additions & 0 deletions dart/test/protocol/sentry_request_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ void main() {
data: {'key': 'value'},
headers: {'header_key': 'header_value'},
env: {'env_key': 'env_value'},
apiTarget: 'GraphQL',
// ignore: deprecated_member_use_from_same_package
other: {'other_key': 'other_value'},
);
Expand All @@ -23,6 +24,7 @@ void main() {
'data': {'key': 'value'},
'headers': {'header_key': 'header_value'},
'env': {'env_key': 'env_value'},
'api_target': 'GraphQL',
'other': {'other_key': 'other_value'},
};

Expand Down
2 changes: 2 additions & 0 deletions dart/test/protocol/sentry_response_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ void main() {
statusCode: 200,
headers: {'header_key': 'header_value'},
cookies: 'foo=bar, another=cookie',
data: 'foo',
);

final sentryResponseJson = <String, dynamic>{
'body_size': 42,
'status_code': 200,
'headers': {'header_key': 'header_value'},
'cookies': 'foo=bar, another=cookie',
'data': 'foo',
};

group('json', () {
Expand Down