Skip to content

Commit 43f6b19

Browse files
authored
Feat: Support Attachment.addToTransactions (#709)
1 parent 6206e85 commit 43f6b19

File tree

8 files changed

+166
-5
lines changed

8 files changed

+166
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Unreleased
22

3+
* Feat: Support Attachment.addToTransactions (#709)
34
* Fix: captureTransaction should return emptyId when transaction is discarded (#713)
45

56
# 6.3.0-beta.3

dart/lib/src/sentry_attachment/sentry_attachment.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,24 @@ class SentryAttachment {
3333
required this.filename,
3434
String? attachmentType,
3535
this.contentType,
36+
bool? addToTransactions,
3637
}) : _loader = loader,
37-
attachmentType = attachmentType ?? typeAttachmentDefault;
38+
attachmentType = attachmentType ?? typeAttachmentDefault,
39+
addToTransactions = addToTransactions ?? false;
3840

3941
/// Creates an [SentryAttachment] from a [Uint8List]
4042
SentryAttachment.fromUint8List(
4143
Uint8List bytes,
4244
String fileName, {
4345
String? contentType,
4446
String? attachmentType,
47+
bool? addToTransactions,
4548
}) : this.fromLoader(
4649
attachmentType: attachmentType,
4750
loader: () => bytes,
4851
filename: fileName,
4952
contentType: contentType,
53+
addToTransactions: addToTransactions,
5054
);
5155

5256
/// Creates an [SentryAttachment] from a [List<int>]
@@ -55,11 +59,13 @@ class SentryAttachment {
5559
String fileName, {
5660
String? contentType,
5761
String? attachmentType,
62+
bool? addToTransactions,
5863
}) : this.fromLoader(
5964
attachmentType: attachmentType,
6065
loader: () => Uint8List.fromList(bytes),
6166
filename: fileName,
6267
contentType: contentType,
68+
addToTransactions: addToTransactions,
6369
);
6470

6571
/// Creates an [SentryAttachment] from [ByteData]
@@ -68,11 +74,13 @@ class SentryAttachment {
6874
String fileName, {
6975
String? contentType,
7076
String? attachmentType,
77+
bool? addToTransactions,
7178
}) : this.fromLoader(
7279
attachmentType: attachmentType,
7380
loader: () => bytes.buffer.asUint8List(),
7481
filename: fileName,
7582
contentType: contentType,
83+
addToTransactions: addToTransactions,
7684
);
7785

7886
/// Attachment type.
@@ -91,4 +99,8 @@ class SentryAttachment {
9199
/// Attachment content type.
92100
/// Inferred by Sentry if it's not given.
93101
final String? contentType;
102+
103+
/// If true, attachment should be added to every transaction.
104+
/// Defaults to false.
105+
final bool addToTransactions;
94106
}

dart/lib/src/sentry_client.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,11 @@ class SentryClient {
260260
}
261261

262262
final id = await captureEnvelope(
263-
SentryEnvelope.fromTransaction(preparedTransaction, _options.sdk));
263+
SentryEnvelope.fromTransaction(preparedTransaction, _options.sdk,
264+
attachments: scope?.attachements
265+
.where((element) => element.addToTransactions)
266+
.toList()),
267+
);
264268
return id ?? SentryId.empty();
265269
}
266270

dart/lib/src/sentry_envelope.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,16 @@ class SentryEnvelope {
4747
/// Create an [SentryEnvelope] with containing one [SentryEnvelopeItem] which holds the [SentryTransaction] data.
4848
factory SentryEnvelope.fromTransaction(
4949
SentryTransaction transaction,
50-
SdkVersion sdkVersion,
51-
) {
50+
SdkVersion sdkVersion, {
51+
List<SentryAttachment>? attachments,
52+
}) {
5253
return SentryEnvelope(
5354
SentryEnvelopeHeader(transaction.eventId, sdkVersion),
54-
[SentryEnvelopeItem.fromTransaction(transaction)],
55+
[
56+
SentryEnvelopeItem.fromTransaction(transaction),
57+
if (attachments != null)
58+
...attachments.map((e) => SentryEnvelopeItem.fromAttachment(e))
59+
],
5560
);
5661
}
5762

dart/test/sentry_attachment_test.dart

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,81 @@ void main() {
8585
);
8686
});
8787
});
88+
89+
group('addToTransactions', () {
90+
test('defaults to false fromLoader', () async {
91+
final attachment = SentryAttachment.fromLoader(
92+
loader: () => Uint8List.fromList([0, 0, 0, 0]),
93+
filename: 'test.txt',
94+
);
95+
96+
expect(attachment.addToTransactions, false);
97+
});
98+
99+
test('defaults to false fromIntList', () async {
100+
final attachment = SentryAttachment.fromIntList([0, 0, 0, 0], 'test.txt');
101+
102+
expect(attachment.addToTransactions, false);
103+
});
104+
105+
test('defaults to false fromUint8List', () async {
106+
final attachment = SentryAttachment.fromUint8List(
107+
Uint8List.fromList([0, 0, 0, 0]),
108+
'test.txt',
109+
);
110+
111+
expect(attachment.addToTransactions, false);
112+
});
113+
114+
test('defaults to false fromByteData', () async {
115+
final attachment = SentryAttachment.fromByteData(
116+
ByteData.sublistView(Uint8List.fromList([0, 0, 0, 0])),
117+
'test.txt',
118+
);
119+
120+
expect(attachment.addToTransactions, false);
121+
});
122+
123+
test('set fromLoader', () async {
124+
final attachment = SentryAttachment.fromLoader(
125+
loader: () => Uint8List.fromList([0, 0, 0, 0]),
126+
filename: 'test.txt',
127+
addToTransactions: true,
128+
);
129+
130+
expect(attachment.addToTransactions, true);
131+
});
132+
133+
test('defaults to false fromIntList', () async {
134+
final attachment = SentryAttachment.fromIntList(
135+
[0, 0, 0, 0],
136+
'test.txt',
137+
addToTransactions: true,
138+
);
139+
140+
expect(attachment.addToTransactions, true);
141+
});
142+
143+
test('defaults to false fromUint8List', () async {
144+
final attachment = SentryAttachment.fromUint8List(
145+
Uint8List.fromList([0, 0, 0, 0]),
146+
'test.txt',
147+
addToTransactions: true,
148+
);
149+
150+
expect(attachment.addToTransactions, true);
151+
});
152+
153+
test('defaults to false fromByteData', () async {
154+
final attachment = SentryAttachment.fromByteData(
155+
ByteData.sublistView(Uint8List.fromList([0, 0, 0, 0])),
156+
'test.txt',
157+
addToTransactions: true,
158+
);
159+
160+
expect(attachment.addToTransactions, true);
161+
});
162+
});
88163
}
89164

90165
class Fixture {

dart/test/sentry_client_test.dart

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import 'dart:async';
22
import 'dart:convert';
3+
import 'dart:typed_data';
34

45
import 'package:sentry/sentry.dart';
6+
import 'package:sentry/src/sentry_item_type.dart';
57
import 'package:sentry/src/sentry_stack_trace_factory.dart';
68
import 'package:sentry/src/sentry_tracer.dart';
79
import 'package:test/test.dart';
@@ -347,6 +349,64 @@ void main() {
347349
expect(capturedEvent['exception'], isNull);
348350
});
349351

352+
test('attachments not added to captured transaction per default', () async {
353+
final attachment = SentryAttachment.fromUint8List(
354+
Uint8List.fromList([0, 0, 0, 0]),
355+
'test.txt',
356+
);
357+
final scope = Scope(fixture.options);
358+
scope.addAttachment(attachment);
359+
360+
final client = fixture.getSut();
361+
final tr = SentryTransaction(fixture.tracer);
362+
await client.captureTransaction(tr, scope: scope);
363+
364+
final capturedEnvelope = (fixture.transport).envelopes.first;
365+
final capturedAttachments = capturedEnvelope.items
366+
.where((item) => item.header.type == SentryItemType.attachment);
367+
368+
expect(capturedAttachments.isEmpty, true);
369+
});
370+
371+
test('attachments added to captured event', () async {
372+
final attachment = SentryAttachment.fromUint8List(
373+
Uint8List.fromList([0, 0, 0, 0]),
374+
'test.txt',
375+
addToTransactions: true,
376+
);
377+
final scope = Scope(fixture.options);
378+
scope.addAttachment(attachment);
379+
380+
final client = fixture.getSut();
381+
final tr = SentryTransaction(fixture.tracer);
382+
await client.captureTransaction(tr, scope: scope);
383+
384+
final capturedEnvelope = (fixture.transport).envelopes.first;
385+
final capturedAttachments = capturedEnvelope.items
386+
.where((item) => item.header.type == SentryItemType.attachment);
387+
388+
expect(capturedAttachments.isNotEmpty, true);
389+
});
390+
391+
test('attachments added to captured event per default', () async {
392+
final attachment = SentryAttachment.fromUint8List(
393+
Uint8List.fromList([0, 0, 0, 0]),
394+
'test.txt',
395+
);
396+
final scope = Scope(fixture.options);
397+
scope.addAttachment(attachment);
398+
399+
final client = fixture.getSut();
400+
final event = SentryEvent();
401+
await client.captureEvent(event, scope: scope);
402+
403+
final capturedEnvelope = (fixture.transport).envelopes.first;
404+
final capturedAttachments = capturedEnvelope.items
405+
.where((item) => item.header.type == SentryItemType.attachment);
406+
407+
expect(capturedAttachments.isNotEmpty, true);
408+
});
409+
350410
test('should return empty for when transaction is discarded', () async {
351411
final client = fixture.getSut(eventProcessor: DropAllEventProcessor());
352412
final tr = SentryTransaction(fixture.tracer);

flutter/lib/src/flutter_sentry_attachment.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class FlutterSentryAttachment extends SentryAttachment {
1717
AssetBundle? bundle,
1818
String? type,
1919
String? contentType,
20+
bool? addToTransactions,
2021
}) : super.fromLoader(
2122
loader: () async {
2223
final data = await (bundle ?? rootBundle).load(key);
@@ -25,5 +26,6 @@ class FlutterSentryAttachment extends SentryAttachment {
2526
filename: filename ?? Uri.parse(key).pathSegments.last,
2627
attachmentType: type,
2728
contentType: contentType,
29+
addToTransactions: addToTransactions,
2830
);
2931
}

flutter/test/flutter_sentry_attachment_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ void main() {
1010
final attachment = FlutterSentryAttachment.fromAsset(
1111
'foobar.txt',
1212
bundle: TestAssetBundle(),
13+
addToTransactions: true,
1314
);
1415

1516
expect(attachment.attachmentType, SentryAttachment.typeAttachmentDefault);
1617
expect(attachment.contentType, isNull);
1718
expect(attachment.filename, 'foobar.txt');
19+
expect(attachment.addToTransactions, true);
1820
await expectLater(await attachment.bytes, [102, 111, 111, 32, 98, 97, 114]);
1921
});
2022
}

0 commit comments

Comments
 (0)