Skip to content

Commit 25e9b59

Browse files
authored
refactor: use options.clock wherever possible (#1110)
1 parent 2f2a9a9 commit 25e9b59

15 files changed

+88
-27
lines changed

dart/lib/src/default_integrations.dart

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class RunZonedGuardedIntegration extends Integration {
4848
final event = SentryEvent(
4949
throwable: throwableMechanism,
5050
level: SentryLevel.fatal,
51+
timestamp: hub.options.clock(),
5152
);
5253

5354
await hub.captureEvent(event, stackTrace: stackTrace);

dart/lib/src/http_client/failed_request_client.dart

+1
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class FailedRequestClient extends BaseClient {
198198
final event = SentryEvent(
199199
throwable: throwableMechanism,
200200
request: sentryRequest,
201+
timestamp: _hub.options.clock(),
201202
);
202203

203204
if (response != null) {

dart/lib/src/isolate_error_integration.dart

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ Future<void> handleIsolateError(
7272
final event = SentryEvent(
7373
throwable: throwableMechanism,
7474
level: SentryLevel.fatal,
75+
timestamp: hub.options.clock(),
7576
);
7677

7778
await hub.captureEvent(event, stackTrace: stackTrace);

dart/lib/src/protocol/sentry_span.dart

+6-6
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class SentrySpan extends ISentrySpan {
3232
this.samplingDecision,
3333
Function({DateTime? endTimestamp})? finishedCallback,
3434
}) {
35-
_startTimestamp = startTimestamp?.toUtc() ?? getUtcDateTime();
35+
_startTimestamp = startTimestamp?.toUtc() ?? _hub.options.clock();
3636
_finishedCallback = finishedCallback;
3737
}
3838

@@ -42,20 +42,20 @@ class SentrySpan extends ISentrySpan {
4242
return;
4343
}
4444

45-
final utcDateTime = getUtcDateTime();
46-
4745
if (status != null) {
4846
_status = status;
4947
}
5048

51-
if (endTimestamp?.isBefore(_startTimestamp) ?? false) {
49+
if (endTimestamp == null) {
50+
_endTimestamp = _hub.options.clock();
51+
} else if (endTimestamp.isBefore(_startTimestamp)) {
5252
_hub.options.logger(
5353
SentryLevel.warning,
5454
'End timestamp ($endTimestamp) cannot be before start timestamp ($_startTimestamp)',
5555
);
56-
_endTimestamp = utcDateTime;
56+
_endTimestamp = _hub.options.clock();
5757
} else {
58-
_endTimestamp = endTimestamp?.toUtc() ?? utcDateTime;
58+
_endTimestamp = endTimestamp.toUtc();
5959
}
6060

6161
// associate error

dart/lib/src/sentry_options.dart

+26-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class SentryOptions {
4141

4242
/// If [clock] is provided, it is used to get time instead of the system
4343
/// clock. This is useful in tests. Should be an implementation of [ClockProvider].
44+
/// The ClockProvider is expected to return UTC time.
45+
@internal
4446
ClockProvider clock = getUtcDateTime;
4547

4648
int _maxBreadcrumbs = 100;
@@ -87,6 +89,7 @@ class SentryOptions {
8789
_maxSpans = maxSpans;
8890
}
8991

92+
// ignore: deprecated_member_use_from_same_package
9093
SentryLogger _logger = noOpLogger;
9194

9295
/// Logger interface to log useful debugging information if debug is enabled
@@ -117,10 +120,12 @@ class SentryOptions {
117120

118121
set debug(bool newValue) {
119122
_debug = newValue;
123+
// ignore: deprecated_member_use_from_same_package
120124
if (_debug == true && logger == noOpLogger) {
121-
_logger = dartLogger;
125+
_logger = _debugLogger;
122126
}
123-
if (_debug == false && logger == dartLogger) {
127+
if (_debug == false && logger == _debugLogger) {
128+
// ignore: deprecated_member_use_from_same_package
124129
_logger = noOpLogger;
125130
}
126131
}
@@ -359,6 +364,23 @@ class SentryOptions {
359364
@internal
360365
late SentryClientAttachmentProcessor clientAttachmentProcessor =
361366
SentryClientAttachmentProcessor();
367+
368+
void _debugLogger(
369+
SentryLevel level,
370+
String message, {
371+
String? logger,
372+
Object? exception,
373+
StackTrace? stackTrace,
374+
}) {
375+
log(
376+
'[${level.name}] $message',
377+
level: level.toDartLogLevel(),
378+
name: logger ?? 'sentry',
379+
time: clock(),
380+
error: exception,
381+
stackTrace: stackTrace,
382+
);
383+
}
362384
}
363385

364386
/// This function is called with an SDK specific event object and can return a modified event
@@ -391,6 +413,7 @@ typedef TracesSamplerCallback = double? Function(
391413
SentrySamplingContext samplingContext);
392414

393415
/// A NoOp logger that does nothing
416+
@Deprecated('This will be made private or removed in the future')
394417
void noOpLogger(
395418
SentryLevel level,
396419
String message, {
@@ -400,6 +423,7 @@ void noOpLogger(
400423
}) {}
401424

402425
/// A Logger that prints out the level and message
426+
@Deprecated('This will be made private or removed in the future')
403427
void dartLogger(
404428
SentryLevel level,
405429
String message, {

dart/lib/src/sentry_tracer.dart

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

33
import 'package:intl/intl.dart';
44
import 'package:meta/meta.dart';
5-
import 'utils.dart';
65

76
import '../sentry.dart';
87
import 'sentry_tracer_finish_status.dart';
@@ -72,7 +71,7 @@ class SentryTracer extends ISentrySpan {
7271

7372
@override
7473
Future<void> finish({SpanStatus? status, DateTime? endTimestamp}) async {
75-
final commonEndTimestamp = endTimestamp ?? getUtcDateTime();
74+
final commonEndTimestamp = endTimestamp ?? _hub.options.clock();
7675
_autoFinishAfterTimer?.cancel();
7776
_finishStatus = SentryTracerFinishStatus.finishing(status);
7877
if (!_rootSpan.finished &&

dart/test/sentry_options_test.dart

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ void main() {
3434

3535
test('SentryLogger sets a diagnostic logger', () {
3636
final options = SentryOptions(dsn: fakeDsn);
37+
// ignore: deprecated_member_use_from_same_package
38+
expect(options.logger, noOpLogger);
39+
// ignore: deprecated_member_use_from_same_package
3740
options.logger = dartLogger;
3841

39-
expect(false, options.logger == noOpLogger);
42+
// ignore: deprecated_member_use_from_same_package
43+
expect(options.logger, isNot(noOpLogger));
4044
});
4145

4246
test('tracesSampler is null by default', () {

dart/test/sentry_test.dart

+6-3
Original file line numberDiff line numberDiff line change
@@ -342,20 +342,23 @@ void main() {
342342
}, options: sentryOptions);
343343
});
344344

345-
test('options.logger is not dartLogger after debug = false', () async {
345+
test('options.logger is set by setting the debug flag', () async {
346346
final sentryOptions =
347347
SentryOptions(dsn: fakeDsn, checker: FakePlatformChecker.debugMode());
348348

349349
await Sentry.init((options) {
350350
options.dsn = fakeDsn;
351351
options.debug = true;
352-
expect(options.logger, dartLogger);
352+
// ignore: deprecated_member_use_from_same_package
353+
expect(options.logger, isNot(noOpLogger));
353354

354355
options.debug = false;
356+
// ignore: deprecated_member_use_from_same_package
355357
expect(options.logger, noOpLogger);
356358
}, options: sentryOptions);
357359

358-
expect(sentryOptions.logger == dartLogger, false);
360+
// ignore: deprecated_member_use_from_same_package
361+
expect(sentryOptions.logger, isNot(dartLogger));
359362
});
360363

361364
group("Sentry init optionsConfiguration", () {

flutter/lib/src/integrations/flutter_error_integration.dart

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class FlutterErrorIntegration extends Integration<SentryFlutterOptions> {
7474
contexts: flutterErrorDetails.isNotEmpty
7575
? (Contexts()..['flutter_error_details'] = flutterErrorDetails)
7676
: null,
77+
// ignore: invalid_use_of_internal_member
78+
timestamp: options.clock(),
7779
);
7880

7981
await hub.captureEvent(event, stackTrace: errorDetails.stack);

flutter/lib/src/integrations/native_app_start_integration.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ class NativeAppStartIntegration extends Integration<SentryFlutterOptions> {
2424
'Scheduler binding is null. Can\'t auto detect app start time.');
2525
} else {
2626
schedulerBinding.addPostFrameCallback((timeStamp) {
27-
_native.appStartEnd = DateTime.now().toUtc();
27+
// ignore: invalid_use_of_internal_member
28+
_native.appStartEnd = options.clock();
2829
});
2930
}
3031
}

flutter/lib/src/integrations/on_error_integration.dart

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class OnErrorIntegration implements Integration<SentryFlutterOptions> {
5656
var event = SentryEvent(
5757
throwable: throwableMechanism,
5858
level: SentryLevel.fatal,
59+
// ignore: invalid_use_of_internal_member
60+
timestamp: options.clock(),
5961
);
6062

6163
// unawaited future

flutter/lib/src/navigation/sentry_navigator_observer.dart

+6
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class SentryNavigatorObserver extends RouteObserver<PageRoute<dynamic>> {
132132
navigationType: type,
133133
from: _routeNameExtractor?.call(from) ?? from,
134134
to: _routeNameExtractor?.call(to) ?? to,
135+
// ignore: invalid_use_of_internal_member
136+
timestamp: _hub.options.clock(),
135137
data: _additionalInfoProvider?.call(from, to),
136138
));
137139
}
@@ -232,6 +234,7 @@ class RouteObserverBreadcrumb extends Breadcrumb {
232234
RouteSettings? from,
233235
RouteSettings? to,
234236
SentryLevel? level,
237+
DateTime? timestamp,
235238
Map<String, dynamic>? data,
236239
}) {
237240
final dynamic fromArgs = _formatArgs(from?.arguments);
@@ -243,6 +246,7 @@ class RouteObserverBreadcrumb extends Breadcrumb {
243246
toArgs: toArgs,
244247
navigationType: navigationType,
245248
level: level,
249+
timestamp: timestamp,
246250
data: data,
247251
);
248252
}
@@ -254,11 +258,13 @@ class RouteObserverBreadcrumb extends Breadcrumb {
254258
String? to,
255259
dynamic toArgs,
256260
SentryLevel? level,
261+
DateTime? timestamp,
257262
Map<String, dynamic>? data,
258263
}) : super(
259264
category: _navigationKey,
260265
type: _navigationKey,
261266
level: level,
267+
timestamp: timestamp,
262268
data: <String, dynamic>{
263269
'state': navigationType,
264270
if (from != null) 'from': from,

flutter/lib/src/widgets_binding_observer.dart

+10
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class SentryWidgetsBindingObserver with WidgetsBindingObserver {
7272
data: <String, String>{
7373
'state': _lifecycleToString(state),
7474
},
75+
// ignore: invalid_use_of_internal_member
76+
timestamp: _options.clock(),
7577
));
7678
}
7779

@@ -95,6 +97,8 @@ class SentryWidgetsBindingObserver with WidgetsBindingObserver {
9597
category: 'device.screen',
9698
type: 'navigation',
9799
data: data,
100+
// ignore: invalid_use_of_internal_member
101+
timestamp: _options.clock(),
98102
));
99103
}
100104

@@ -117,6 +121,8 @@ class SentryWidgetsBindingObserver with WidgetsBindingObserver {
117121
data: <String, String>{
118122
'action': 'BRIGHTNESS_CHANGED_TO_${brightnessDescription.toUpperCase()}'
119123
},
124+
// ignore: invalid_use_of_internal_member
125+
timestamp: _options.clock(),
120126
));
121127
}
122128

@@ -136,6 +142,8 @@ class SentryWidgetsBindingObserver with WidgetsBindingObserver {
136142
data: <String, String>{
137143
'action': 'TEXT_SCALE_CHANGED_TO_$newTextScaleFactor'
138144
},
145+
// ignore: invalid_use_of_internal_member
146+
timestamp: _options.clock(),
139147
));
140148
}
141149

@@ -162,6 +170,8 @@ class SentryWidgetsBindingObserver with WidgetsBindingObserver {
162170
},
163171
// This is kinda bad. Therefore this gets added as a warning.
164172
level: SentryLevel.warning,
173+
// ignore: invalid_use_of_internal_member
174+
timestamp: _options.clock(),
165175
));
166176
}
167177

flutter/test/integrations/native_app_start_integration_test.dart

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@TestOn('vm')
22

33
import 'package:flutter_test/flutter_test.dart';
4+
import 'package:mockito/mockito.dart';
45
import 'package:sentry_flutter/sentry_flutter.dart';
56
import 'package:sentry_flutter/src/integrations/native_app_start_integration.dart';
67
import 'package:sentry_flutter/src/sentry_native.dart';
@@ -25,7 +26,7 @@ void main() {
2526
fixture.native.appStartEnd = DateTime.fromMillisecondsSinceEpoch(10);
2627
fixture.wrapper.nativeAppStart = NativeAppStart(0, true);
2728

28-
fixture.getNativeAppStartIntegration().call(MockHub(), fixture.options);
29+
fixture.getNativeAppStartIntegration().call(fixture.hub, fixture.options);
2930

3031
final tracer = fixture.createTracer();
3132
final transaction = SentryTransaction(tracer);
@@ -44,7 +45,7 @@ void main() {
4445
fixture.native.appStartEnd = DateTime.fromMillisecondsSinceEpoch(10);
4546
fixture.wrapper.nativeAppStart = NativeAppStart(0, true);
4647

47-
fixture.getNativeAppStartIntegration().call(MockHub(), fixture.options);
48+
fixture.getNativeAppStartIntegration().call(fixture.hub, fixture.options);
4849

4950
final tracer = fixture.createTracer();
5051
final transaction = SentryTransaction(tracer);
@@ -63,7 +64,7 @@ void main() {
6364
fixture.wrapper.nativeAppStart = NativeAppStart(0, true);
6465
final measurement = SentryMeasurement.warmAppStart(Duration(seconds: 1));
6566

66-
fixture.getNativeAppStartIntegration().call(MockHub(), fixture.options);
67+
fixture.getNativeAppStartIntegration().call(fixture.hub, fixture.options);
6768

6869
final tracer = fixture.createTracer();
6970
final transaction = SentryTransaction(tracer).copyWith();
@@ -83,7 +84,7 @@ void main() {
8384
fixture.native.appStartEnd = DateTime.fromMillisecondsSinceEpoch(60001);
8485
fixture.wrapper.nativeAppStart = NativeAppStart(0, true);
8586

86-
fixture.getNativeAppStartIntegration().call(MockHub(), fixture.options);
87+
fixture.getNativeAppStartIntegration().call(fixture.hub, fixture.options);
8788

8889
final tracer = fixture.createTracer();
8990
final transaction = SentryTransaction(tracer);
@@ -97,13 +98,15 @@ void main() {
9798
}
9899

99100
class Fixture {
101+
final hub = MockHub();
100102
final options = SentryFlutterOptions(dsn: fakeDsn);
101103
final wrapper = MockNativeChannel();
102104
late final native = SentryNative();
103105

104106
Fixture() {
105107
native.setNativeChannel(wrapper);
106108
native.reset();
109+
when(hub.options).thenReturn(options);
107110
}
108111

109112
NativeAppStartIntegration getNativeAppStartIntegration() {
@@ -124,6 +127,6 @@ class Fixture {
124127
'op',
125128
samplingDecision: SentryTracesSamplingDecision(sampled!),
126129
);
127-
return SentryTracer(context, MockHub());
130+
return SentryTracer(context, hub);
128131
}
129132
}

0 commit comments

Comments
 (0)