Skip to content

Commit 5ed2676

Browse files
committed
Merge branch 'main' into chore/import-hybridsdk-header
2 parents 9df7281 + 8c7dd11 commit 5ed2676

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+707
-41
lines changed

.github/workflows/analyze.yml

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ on:
1515
default: 100
1616

1717
jobs:
18+
cancel-previous-workflow:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Cancel Previous Runs
22+
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # [email protected]
23+
with:
24+
access_token: ${{ github.token }}
25+
1826
analyze:
1927
runs-on: ubuntu-latest
2028
timeout-minutes: 20

.github/workflows/dart.yml

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ on:
1010
- 'dio/**'
1111

1212
jobs:
13+
cancel-previous-workflow:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Cancel Previous Runs
17+
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # [email protected]
18+
with:
19+
access_token: ${{ github.token }}
20+
1321
build:
1422
name: Build ${{matrix.sdk}} on ${{matrix.os}}
1523
runs-on: ${{ matrix.os }}

.github/workflows/dio.yml

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ on:
1010
- 'flutter/**'
1111

1212
jobs:
13+
cancel-previous-workflow:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Cancel Previous Runs
17+
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # [email protected]
18+
with:
19+
access_token: ${{ github.token }}
20+
1321
build:
1422
name: Build ${{matrix.sdk}} on ${{matrix.os}}
1523
runs-on: ${{ matrix.os }}

.github/workflows/e2e_dart.yml

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ env:
1515
SENTRY_DIST: 1
1616

1717
jobs:
18+
cancel-previous-workflow:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Cancel Previous Runs
22+
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # [email protected]
23+
with:
24+
access_token: ${{ github.token }}
25+
1826
build:
1927
name: E2E
2028
runs-on: 'ubuntu-latest'

.github/workflows/flutter.yml

+10-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ on:
1010
- 'dio/**'
1111

1212
jobs:
13+
cancel-previous-workflow:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Cancel Previous Runs
17+
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # [email protected]
18+
with:
19+
access_token: ${{ github.token }}
20+
1321
build:
1422
name: ${{ matrix.target }} | ${{ matrix.os }} | ${{ matrix.sdk }}
1523
runs-on: ${{ matrix.os }}
@@ -81,7 +89,8 @@ jobs:
8189
if: runner.os == 'Linux'
8290
run: |
8391
cd flutter
84-
flutter test --platform chrome --test-randomize-ordering-seed=random
92+
flutter test --platform chrome --test-randomize-ordering-seed=random --exclude-tags canvasKit
93+
flutter test --platform chrome --test-randomize-ordering-seed=random --tags canvasKit --web-renderer canvaskit
8594
8695
- name: Test VM with coverage
8796
if: runner.os != 'macOS'

.github/workflows/logging.yml

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ on:
1010
- 'flutter/**'
1111

1212
jobs:
13+
cancel-previous-workflow:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Cancel Previous Runs
17+
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # [email protected]
18+
with:
19+
access_token: ${{ github.token }}
20+
1321
build:
1422
name: Build ${{matrix.sdk}} on ${{matrix.os}}
1523
runs-on: ${{ matrix.os }}

.github/workflows/metrics.yml

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ on:
1313
tags-ignore: ['**']
1414

1515
jobs:
16+
cancel-previous-workflow:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Cancel Previous Runs
20+
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # [email protected]
21+
with:
22+
access_token: ${{ github.token }}
23+
1624
metrics:
1725
name: ${{ matrix.name }}
1826
runs-on: ${{ matrix.host }}

.github/workflows/min_version_test.yml

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ on:
77
pull_request:
88

99
jobs:
10+
cancel-previous-workflow:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Cancel Previous Runs
14+
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # [email protected]
15+
with:
16+
access_token: ${{ github.token }}
17+
1018
build:
1119
name: Build
1220
runs-on: macos-latest

.github/workflows/web-example-ghpages.yml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
with:
1919
workingDir: flutter/example
2020
customArgs: --source-maps
21+
webRenderer: canvaskit
2122

2223
- name: Upload source maps
2324
run: |

CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
# Changelog
22

3-
## Unreleased
3+
## 6.15.0
4+
5+
### Features
6+
7+
- Feat: Screenshot Attachment ([#1088](https://github.com/getsentry/sentry-dart/pull/1088))
48

59
### Fixes
610

711
- Merging of integrations and packages ([#1111](https://github.com/getsentry/sentry-dart/pull/1111))
812
- Add missing `fragment` for HTTP Client Errors ([#1102](https://github.com/getsentry/sentry-dart/pull/1102))
913
- Sync user name and geo for Android ([#1102](https://github.com/getsentry/sentry-dart/pull/1102))
14+
- Add mechanism to Dio Http Client error ([#1114](https://github.com/getsentry/sentry-dart/pull/1114))
1015

1116
### Dependencies
1217

dart/lib/sentry_private.dart

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// attachments
2+
// ignore: invalid_export_of_internal_element
3+
export 'src/sentry_client_attachment_processor.dart';

dart/lib/src/http_client/failed_request_client.dart

+12-3
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ class FailedRequestClient extends BaseClient {
126126
} else if (failedRequestStatusCodes.containsStatusCode(statusCode)) {
127127
// Capture an exception if the status code is considered bad
128128
capture = true;
129-
reason =
130-
'Event was captured because the request status code was $statusCode';
129+
reason = 'HTTP Client Error with status code: $statusCode';
131130
exception ??= SentryHttpClientError(reason);
132131
}
133132
if (capture) {
@@ -184,7 +183,17 @@ class FailedRequestClient extends BaseClient {
184183
type: 'SentryHttpClient',
185184
description: reason,
186185
);
187-
final throwableMechanism = ThrowableMechanism(mechanism, exception);
186+
187+
bool? snapshot;
188+
if (exception is SentryHttpClientError) {
189+
snapshot = true;
190+
}
191+
192+
final throwableMechanism = ThrowableMechanism(
193+
mechanism,
194+
exception,
195+
snapshot: snapshot,
196+
);
188197

189198
final event = SentryEvent(
190199
throwable: throwableMechanism,

dart/lib/src/sentry_attachment/sentry_attachment.dart

+5
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ class SentryAttachment {
8383
addToTransactions: addToTransactions,
8484
);
8585

86+
SentryAttachment.fromScreenshotData(Uint8List bytes)
87+
: this.fromUint8List(bytes, 'screenshot.png',
88+
contentType: 'image/png',
89+
attachmentType: SentryAttachment.typeAttachmentDefault);
90+
8691
/// Attachment type.
8792
/// Should be one of types given in [AttachmentType].
8893
final String attachmentType;

dart/lib/src/sentry_client.dart

+8-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'sentry_envelope.dart';
1919
import 'client_reports/client_report_recorder.dart';
2020
import 'client_reports/discard_reason.dart';
2121
import 'transport/data_category.dart';
22+
import 'sentry_client_attachment_processor.dart';
2223

2324
/// Default value for [User.ipAddress]. It gets set when an event does not have
2425
/// a user and IP address. Only applies if [SentryOptions.sendDefaultPii] is set
@@ -37,6 +38,9 @@ class SentryClient {
3738

3839
SentryStackTraceFactory get _stackTraceFactory => _options.stackTraceFactory;
3940

41+
SentryClientAttachmentProcessor get _clientAttachmentProcessor =>
42+
_options.clientAttachmentProcessor;
43+
4044
/// Instantiates a client using [SentryOptions]
4145
factory SentryClient(SentryOptions options) {
4246
if (options.sendClientReports) {
@@ -130,12 +134,15 @@ class SentryClient {
130134
preparedEvent = _eventWithRemovedBreadcrumbsIfHandled(preparedEvent);
131135
}
132136

137+
final attachments = await _clientAttachmentProcessor.processAttachments(
138+
scope?.attachments ?? [], preparedEvent);
139+
133140
final envelope = SentryEnvelope.fromEvent(
134141
preparedEvent,
135142
_options.sdk,
136143
dsn: _options.dsn,
137144
traceContext: scope?.span?.traceContext(),
138-
attachments: scope?.attachments,
145+
attachments: attachments.isNotEmpty ? attachments : null,
139146
);
140147

141148
final id = await captureEnvelope(envelope);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import 'dart:async';
2+
3+
import 'package:meta/meta.dart';
4+
5+
import './sentry_attachment/sentry_attachment.dart';
6+
import './protocol/sentry_event.dart';
7+
8+
@internal
9+
class SentryClientAttachmentProcessor {
10+
Future<List<SentryAttachment>> processAttachments(
11+
List<SentryAttachment> attachments, SentryEvent event) async {
12+
return attachments;
13+
}
14+
}

dart/lib/src/sentry_exception_factory.dart

+5
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ class SentryExceptionFactory {
1717
}) {
1818
var throwable = exception;
1919
Mechanism? mechanism;
20+
bool? snapshot;
2021
if (exception is ThrowableMechanism) {
2122
throwable = exception.throwable;
2223
mechanism = exception.mechanism;
24+
snapshot = exception.snapshot;
2325
}
2426

2527
if (throwable is Error) {
@@ -29,6 +31,8 @@ class SentryExceptionFactory {
2931
// hence we check again if stackTrace is null and if not, read the current stack trace
3032
// but only if attachStacktrace is enabled
3133
if (_options.attachStacktrace) {
34+
// TODO: snapshot=true if stackTrace is null
35+
// Requires a major breaking change because of grouping
3236
stackTrace ??= StackTrace.current;
3337
}
3438

@@ -39,6 +43,7 @@ class SentryExceptionFactory {
3943
if (frames.isNotEmpty) {
4044
sentryStackTrace = SentryStackTrace(
4145
frames: frames,
46+
snapshot: snapshot,
4247
);
4348
}
4449
}

dart/lib/src/sentry_options.dart

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:meta/meta.dart';
55
import 'package:http/http.dart';
66

77
import '../sentry.dart';
8+
import '../sentry_private.dart';
89
import 'client_reports/client_report_recorder.dart';
910
import 'client_reports/noop_client_report_recorder.dart';
1011
import 'sentry_exception_factory.dart';
@@ -354,6 +355,10 @@ class SentryOptions {
354355
@internal
355356
late SentryStackTraceFactory stackTraceFactory =
356357
SentryStackTraceFactory(this);
358+
359+
@internal
360+
late SentryClientAttachmentProcessor clientAttachmentProcessor =
361+
SentryClientAttachmentProcessor();
357362
}
358363

359364
/// This function is called with an SDK specific event object and can return a modified event

dart/lib/src/throwable_mechanism.dart

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@ import 'protocol/mechanism.dart';
44
class ThrowableMechanism implements Exception {
55
final Mechanism _mechanism;
66
final dynamic _throwable;
7+
final bool? _snapshot;
78

8-
ThrowableMechanism(this._mechanism, this._throwable);
9+
ThrowableMechanism(
10+
this._mechanism,
11+
this._throwable, {
12+
bool? snapshot,
13+
}) : _snapshot = snapshot;
914

1015
Mechanism get mechanism => _mechanism;
1116

1217
dynamic get throwable => _throwable;
18+
19+
bool? get snapshot => _snapshot;
1320
}

dart/lib/src/version.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
library version;
1010

1111
/// The SDK version reported to Sentry.io in the submitted events.
12-
const String sdkVersion = '6.14.0';
12+
const String sdkVersion = '6.15.0';
1313

1414
String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName;
1515

dart/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: sentry
2-
version: 6.14.0
2+
version: 6.15.0
33
description: >
44
A crash reporting library for Dart that sends crash reports to Sentry.io.
55
This library supports Dart VM and Web. For Flutter consider sentry_flutter instead.

dart/test/http_client/failed_request_client_test.dart

+4-2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void main() {
4848
final mechanism = exception?.mechanism;
4949

5050
expect(exception?.stackTrace, isNotNull);
51+
expect(exception?.stackTrace!.snapshot, isNull);
5152
expect(mechanism?.type, 'SentryHttpClient');
5253

5354
final request = eventCall.request;
@@ -101,14 +102,15 @@ void main() {
101102
expect(mechanism?.type, 'SentryHttpClient');
102103
expect(
103104
mechanism?.description,
104-
'Event was captured because the request status code was 404',
105+
'HTTP Client Error with status code: 404',
105106
);
106107

107108
expect(exception?.type, 'SentryHttpClientError');
108109
expect(
109110
exception?.value,
110-
'Exception: Event was captured because the request status code was 404',
111+
'Exception: HTTP Client Error with status code: 404',
111112
);
113+
expect(exception?.stackTrace?.snapshot, true);
112114

113115
final request = eventCall.request;
114116
expect(request, isNotNull);

dart/test/mocks.dart

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:async';
22

33
import 'package:sentry/sentry.dart';
4+
import 'package:sentry/sentry_private.dart';
45
import 'package:sentry/src/transport/rate_limiter.dart';
56

67
final fakeDsn = 'https://[email protected]/1234567';
@@ -160,3 +161,23 @@ class MockRateLimiter implements RateLimiter {
160161
this.errorCode = errorCode;
161162
}
162163
}
164+
165+
enum MockAttachmentProcessorMode { filter, add }
166+
167+
/// Filtering out all attachments.
168+
class MockAttachmentProcessor implements SentryClientAttachmentProcessor {
169+
MockAttachmentProcessorMode mode;
170+
171+
MockAttachmentProcessor(this.mode);
172+
173+
@override
174+
Future<List<SentryAttachment>> processAttachments(
175+
List<SentryAttachment> attachments, SentryEvent event) async {
176+
switch (mode) {
177+
case MockAttachmentProcessorMode.filter:
178+
return <SentryAttachment>[];
179+
case MockAttachmentProcessorMode.add:
180+
return <SentryAttachment>[SentryAttachment.fromIntList([], "added")];
181+
}
182+
}
183+
}

0 commit comments

Comments
 (0)