Skip to content

Commit f49a663

Browse files
committed
Merge remote-tracking branch 'origin/main' into feature/frame-tracking
2 parents d435299 + 6206e85 commit f49a663

36 files changed

Lines changed: 822 additions & 28 deletions

CHANGELOG.md

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

3+
* Fix: captureTransaction should return emptyId when transaction is discarded (#713)
4+
5+
# 6.3.0-beta.3
6+
7+
* Feat: Auto transactions duration trimming (#702)
8+
* Add `SentryAssetBundle` for automatic spans for asset loading (#685)
39
* Feat: Configure idle transaction duration (#705)
410
* Fix: `maxRequestBodySize` should be `never` by default when using the FailedRequestClientAdapter directly (#701)
511

dart/lib/src/hub.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ class Hub {
342342
bool? bindToScope,
343343
bool? waitForChildren,
344344
Duration? autoFinishAfter,
345+
bool? trimEnd,
345346
Map<String, dynamic>? customSamplingContext,
346347
}) =>
347348
startTransactionWithContext(
@@ -353,6 +354,7 @@ class Hub {
353354
bindToScope: bindToScope,
354355
waitForChildren: waitForChildren,
355356
autoFinishAfter: autoFinishAfter,
357+
trimEnd: trimEnd,
356358
customSamplingContext: customSamplingContext,
357359
);
358360

@@ -363,6 +365,7 @@ class Hub {
363365
bool? bindToScope,
364366
bool? waitForChildren,
365367
Duration? autoFinishAfter,
368+
bool? trimEnd,
366369
}) {
367370
if (!_isEnabled) {
368371
_options.logger(
@@ -391,6 +394,7 @@ class Hub {
391394
this,
392395
waitForChildren: waitForChildren ?? false,
393396
autoFinishAfter: autoFinishAfter,
397+
trimEnd: trimEnd ?? false,
394398
);
395399
if (bindToScope ?? false) {
396400
item.scope.span = tracer;

dart/lib/src/hub_adapter.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,15 @@ class HubAdapter implements Hub {
104104
bool? bindToScope,
105105
bool? waitForChildren,
106106
Duration? autoFinishAfter,
107+
bool? trimEnd,
107108
}) =>
108109
Sentry.startTransactionWithContext(
109110
transactionContext,
110111
customSamplingContext: customSamplingContext,
111112
bindToScope: bindToScope,
112113
waitForChildren: waitForChildren,
113114
autoFinishAfter: autoFinishAfter,
115+
trimEnd: trimEnd,
114116
);
115117

116118
@override
@@ -121,6 +123,7 @@ class HubAdapter implements Hub {
121123
bool? bindToScope,
122124
bool? waitForChildren,
123125
Duration? autoFinishAfter,
126+
bool? trimEnd,
124127
Map<String, dynamic>? customSamplingContext,
125128
}) =>
126129
Sentry.startTransaction(
@@ -130,6 +133,7 @@ class HubAdapter implements Hub {
130133
bindToScope: bindToScope,
131134
waitForChildren: waitForChildren,
132135
autoFinishAfter: autoFinishAfter,
136+
trimEnd: trimEnd,
133137
customSamplingContext: customSamplingContext,
134138
);
135139

dart/lib/src/noop_hub.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class NoOpHub implements Hub {
8080
bool? bindToScope,
8181
bool? waitForChildren,
8282
Duration? autoFinishAfter,
83+
bool? trimEnd,
8384
Map<String, dynamic>? customSamplingContext,
8485
}) =>
8586
NoOpSentrySpan();
@@ -91,6 +92,7 @@ class NoOpHub implements Hub {
9192
bool? bindToScope,
9293
bool? waitForChildren,
9394
Duration? autoFinishAfter,
95+
bool? trimEnd,
9496
}) =>
9597
NoOpSentrySpan();
9698

dart/lib/src/protocol/sentry_span.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ class SentrySpan extends ISentrySpan {
3636
}
3737

3838
@override
39-
Future<void> finish({SpanStatus? status}) async {
39+
Future<void> finish({SpanStatus? status, DateTime? endTimestamp}) async {
4040
if (finished) {
4141
return;
4242
}
4343

4444
if (status != null) {
4545
_status = status;
4646
}
47-
_timestamp = getUtcDateTime();
47+
_timestamp = endTimestamp ?? getUtcDateTime();
4848

4949
// associate error
5050
if (_throwable != null) {

dart/lib/src/sentry.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ class Sentry {
231231
bool? bindToScope,
232232
bool? waitForChildren,
233233
Duration? autoFinishAfter,
234+
bool? trimEnd,
234235
Map<String, dynamic>? customSamplingContext,
235236
}) =>
236237
_hub.startTransaction(
@@ -240,6 +241,7 @@ class Sentry {
240241
bindToScope: bindToScope,
241242
waitForChildren: waitForChildren,
242243
autoFinishAfter: autoFinishAfter,
244+
trimEnd: trimEnd,
243245
customSamplingContext: customSamplingContext,
244246
);
245247

@@ -250,13 +252,15 @@ class Sentry {
250252
bool? bindToScope,
251253
bool? waitForChildren,
252254
Duration? autoFinishAfter,
255+
bool? trimEnd,
253256
}) =>
254257
_hub.startTransactionWithContext(
255258
transactionContext,
256259
customSamplingContext: customSamplingContext,
257260
bindToScope: bindToScope,
258261
waitForChildren: waitForChildren,
259262
autoFinishAfter: autoFinishAfter,
263+
trimEnd: trimEnd,
260264
);
261265

262266
/// Gets the current active transaction or span.

dart/lib/src/sentry_client.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ class SentryClient {
261261

262262
final id = await captureEnvelope(
263263
SentryEnvelope.fromTransaction(preparedTransaction, _options.sdk));
264-
return id!;
264+
return id ?? SentryId.empty();
265265
}
266266

267267
/// Reports the [envelope] to Sentry.io.

dart/lib/src/sentry_tracer.dart

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:async';
22

33
import 'package:meta/meta.dart';
4+
import 'utils.dart';
45

56
import '../sentry.dart';
67
import 'sentry_tracer_finish_status.dart';
@@ -16,9 +17,25 @@ class SentryTracer extends ISentrySpan {
1617
final Map<String, dynamic> _extra = {};
1718
Timer? _autoFinishAfterTimer;
1819
var _finishStatus = SentryTracerFinishStatus.notFinishing();
19-
20+
late final bool _trimEnd;
21+
22+
/// If [waitForChildren] is true, this transaction will not finish until all
23+
/// its children are finished.
24+
///
25+
/// When [autoFinishAfter] is provided, started transactions will
26+
/// automatically be finished after this duration.
27+
///
28+
/// If [trimEnd] is true, sets the end timestamp of the transaction to the
29+
/// highest timestamp of child spans, trimming the duration of the
30+
/// transaction. This is useful to discard extra time in the transaction that
31+
/// is not accounted for in child spans, like what happens in the
32+
/// [SentryNavigatorObserver] idle transactions, where we finish the
33+
/// transaction after a given "idle time" and we don't want this "idle time"
34+
/// to be part of the transaction.
2035
SentryTracer(SentryTransactionContext transactionContext, this._hub,
21-
{bool waitForChildren = false, Duration? autoFinishAfter}) {
36+
{bool waitForChildren = false,
37+
Duration? autoFinishAfter,
38+
bool trimEnd = false}) {
2239
_rootSpan = SentrySpan(
2340
this,
2441
transactionContext,
@@ -32,6 +49,7 @@ class SentryTracer extends ISentrySpan {
3249
});
3350
}
3451
name = transactionContext.name;
52+
_trimEnd = trimEnd;
3553
}
3654

3755
@override
@@ -41,7 +59,6 @@ class SentryTracer extends ISentrySpan {
4159
if (!_rootSpan.finished &&
4260
(!_waitForChildren || _haveAllChildrenFinished())) {
4361
_rootSpan.status ??= status;
44-
await _rootSpan.finish();
4562

4663
// finish unfinished spans otherwise transaction gets dropped
4764
for (final span in _children) {
@@ -50,6 +67,23 @@ class SentryTracer extends ISentrySpan {
5067
}
5168
}
5269

70+
var _rootEndTimestamp = getUtcDateTime();
71+
if (_trimEnd && children.isNotEmpty) {
72+
final childEndTimestamps = children
73+
.where((child) => child.endTimestamp != null)
74+
.map((child) => child.endTimestamp!);
75+
76+
if (childEndTimestamps.isNotEmpty) {
77+
final oldestChildEndTimestamp =
78+
childEndTimestamps.reduce((a, b) => a.isAfter(b) ? a : b);
79+
if (_rootEndTimestamp.isAfter(oldestChildEndTimestamp)) {
80+
_rootEndTimestamp = oldestChildEndTimestamp;
81+
}
82+
}
83+
}
84+
85+
await _rootSpan.finish(endTimestamp: _rootEndTimestamp);
86+
5387
// remove from scope
5488
_hub.configureScope((scope) {
5589
if (scope.span == this) {

dart/lib/src/version.dart

Lines changed: 1 addition & 1 deletion
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.3.0-beta.3';
12+
const String sdkVersion = '6.3.0-beta.4';
1313

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

dart/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: sentry
2-
version: 6.3.0-beta.3
2+
version: 6.3.0-beta.4
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.

0 commit comments

Comments
 (0)