Skip to content

Commit 4c2c7c7

Browse files
authored
Do not allow setting measurement if transaction is finished (#1026)
1 parent a62d9aa commit 4c2c7c7

File tree

5 files changed

+66
-27
lines changed

5 files changed

+66
-27
lines changed

CHANGELOG.md

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

3+
## Unreleased
4+
5+
### Fixes
6+
7+
- Tracer does not allow setting measurement if finished ([#1026](https://github.com/getsentry/sentry-dart/pull/1026))
8+
39
## 6.11.1
410

511
### Fixes

dart/lib/src/protocol/sentry_span.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class SentrySpan extends ISentrySpan {
1919

2020
SpanStatus? _status;
2121
final Map<String, String> _tags = {};
22-
void Function({DateTime? endTimestamp})? _finishedCallback;
22+
Function({DateTime? endTimestamp})? _finishedCallback;
2323

2424
@override
2525
final SentryTracesSamplingDecision? samplingDecision;
@@ -62,7 +62,7 @@ class SentrySpan extends ISentrySpan {
6262
if (_throwable != null) {
6363
_hub.setSpanContext(_throwable, this, _tracer.name);
6464
}
65-
_finishedCallback?.call(endTimestamp: _endTimestamp);
65+
await _finishedCallback?.call(endTimestamp: _endTimestamp);
6666
return super.finish(status: status, endTimestamp: _endTimestamp);
6767
}
6868

dart/lib/src/sentry_tracer.dart

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,10 @@ class SentryTracer extends ISentrySpan {
106106
}
107107
}
108108

109-
await _rootSpan.finish(endTimestamp: _rootEndTimestamp);
109+
// the callback should run before because if the span is finished,
110+
// we cannot attach data, its immutable after being finished.
110111
await _onFinish?.call(this);
112+
await _rootSpan.finish(endTimestamp: _rootEndTimestamp);
111113

112114
// remove from scope
113115
await _hub.configureScope((scope) {
@@ -216,21 +218,23 @@ class SentryTracer extends ISentrySpan {
216218
_hub,
217219
samplingDecision: _rootSpan.samplingDecision,
218220
startTimestamp: startTimestamp,
219-
finishedCallback: ({
220-
DateTime? endTimestamp,
221-
}) {
222-
final finishStatus = _finishStatus;
223-
if (finishStatus.finishing) {
224-
finish(status: finishStatus.status, endTimestamp: endTimestamp);
225-
}
226-
},
221+
finishedCallback: _finishedCallback,
227222
);
228223

229224
_children.add(child);
230225

231226
return child;
232227
}
233228

229+
Future<void> _finishedCallback({
230+
DateTime? endTimestamp,
231+
}) async {
232+
final finishStatus = _finishStatus;
233+
if (finishStatus.finishing) {
234+
await finish(status: finishStatus.status, endTimestamp: endTimestamp);
235+
}
236+
}
237+
234238
@override
235239
SpanStatus? get status => _rootSpan.status;
236240

@@ -284,6 +288,9 @@ class SentryTracer extends ISentrySpan {
284288

285289
@override
286290
void setMeasurement(String name, num value, {SentryMeasurementUnit? unit}) {
291+
if (finished) {
292+
return;
293+
}
287294
final measurement = SentryMeasurement(name, value, unit: unit);
288295
_measurements[name] = measurement;
289296
}

dart/test/sentry_tracer_test.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,37 @@ void main() {
373373

374374
expect(sut.startChild('child3'), isA<NoOpSentrySpan>());
375375
});
376+
377+
test('tracer sets measurement', () async {
378+
final sut = fixture.getSut();
379+
380+
sut.setMeasurement('key', 1.0);
381+
382+
expect(sut.measurements['key']!.value, 1.0);
383+
384+
await sut.finish();
385+
});
386+
387+
test('tracer sets custom measurement unit', () async {
388+
final sut = fixture.getSut();
389+
390+
sut.setMeasurement('key', 1.0, unit: SentryMeasurementUnit.hour);
391+
392+
expect(sut.measurements['key']!.value, 1.0);
393+
expect(sut.measurements['key']?.unit, SentryMeasurementUnit.hour);
394+
395+
await sut.finish();
396+
});
397+
398+
test('tracer does not allow setting measurement if finished', () async {
399+
final sut = fixture.getSut();
400+
401+
await sut.finish();
402+
403+
sut.setMeasurement('key', 1.0);
404+
405+
expect(sut.measurements.isEmpty, true);
406+
});
376407
});
377408

378409
group('$SentryBaggageHeader', () {

flutter/lib/src/navigation/sentry_navigator_observer.dart

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// ignore: implementation_imports
2-
import 'package:sentry/src/sentry_tracer.dart';
31
import 'package:flutter/widgets.dart';
42

53
import '../../sentry_flutter.dart';
@@ -181,20 +179,17 @@ class SentryNavigatorObserver extends RouteObserver<PageRoute<dynamic>> {
181179
autoFinishAfter: _autoFinishAfter,
182180
trimEnd: true,
183181
onFinish: (transaction) async {
184-
// ignore: invalid_use_of_internal_member
185-
if (transaction is SentryTracer) {
186-
final nativeFrames = await _native
187-
.endNativeFramesCollection(transaction.context.traceId);
188-
if (nativeFrames != null) {
189-
final measurements = nativeFrames.toMeasurements();
190-
for (final item in measurements.entries) {
191-
final measurement = item.value;
192-
transaction.setMeasurement(
193-
item.key,
194-
measurement.value,
195-
unit: measurement.unit,
196-
);
197-
}
182+
final nativeFrames = await _native
183+
.endNativeFramesCollection(transaction.context.traceId);
184+
if (nativeFrames != null) {
185+
final measurements = nativeFrames.toMeasurements();
186+
for (final item in measurements.entries) {
187+
final measurement = item.value;
188+
transaction.setMeasurement(
189+
item.key,
190+
measurement.value,
191+
unit: measurement.unit,
192+
);
198193
}
199194
}
200195
},

0 commit comments

Comments
 (0)