Skip to content

Commit db3bf92

Browse files
committed
set stacktrace in hint
1 parent f7d358e commit db3bf92

9 files changed

+39
-84
lines changed

dart/lib/src/debug_image_extractor.dart

+11-10
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ class DebugImageExtractor {
1717

1818
final SentryOptions _options;
1919

20-
DebugImage? extractDebugImageFrom(StackTrace stackTrace) {
21-
return _extractDebugInfoFrom(stackTrace).toDebugImage();
20+
DebugImage? extractDebugImageFrom(String stackTraceString) {
21+
return _extractDebugInfoFrom(stackTraceString).toDebugImage();
2222
}
2323

24-
_DebugInfo _extractDebugInfoFrom(StackTrace stackTrace) {
24+
_DebugInfo _extractDebugInfoFrom(String stackTraceString) {
2525
String? buildId;
2626
String? isolateDsoBase;
2727

28-
final lines = stackTrace.toString().split('\n');
28+
final lines = stackTraceString.split('\n');
2929

3030
for (final line in lines) {
3131
if (_isHeaderStartLine(line)) {
@@ -90,12 +90,12 @@ class _DebugInfo {
9090

9191
// Debug identifier is the little-endian UUID representation of the first 16-bytes of
9292
// the build ID on Android
93-
String _convertCodeIdToDebugId(String codeId) {
93+
String? _convertCodeIdToDebugId(String codeId) {
9494
codeId = codeId.replaceAll(' ', '');
9595
if (codeId.length < 32) {
96-
// todo: don't throw
97-
throw ArgumentError(
96+
_options.logger(SentryLevel.warning,
9897
'Code ID must be at least 32 hexadecimal characters long');
98+
return null;
9999
}
100100

101101
final first16Bytes = codeId.substring(0, 32);
@@ -122,10 +122,11 @@ class _DebugInfo {
122122
].join('-');
123123
}
124124

125-
String _hexToUuid(String hex) {
125+
String? _hexToUuid(String hex) {
126126
if (hex.length != 32) {
127-
// todo: don't throw
128-
throw FormatException('Input must be a 32-character hexadecimal string');
127+
_options.logger(SentryLevel.warning,
128+
'Hex input must be a 32-character hexadecimal string');
129+
return null;
129130
}
130131

131132
return '${hex.substring(0, 8)}-'

dart/lib/src/load_dart_debug_images_integration.dart

+7-2
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,24 @@ class LoadDartDebugImagesIntegration extends Integration<SentryOptions> {
1010
}
1111
}
1212

13+
const hintRawStackTraceKey = 'raw_stacktrace';
14+
1315
class _LoadImageIntegrationEventProcessor implements EventProcessor {
1416
_LoadImageIntegrationEventProcessor(this._debugImageExtractor);
1517

1618
final DebugImageExtractor _debugImageExtractor;
1719

1820
@override
1921
Future<SentryEvent?> apply(SentryEvent event, Hint hint) async {
20-
if (!event.needsSymbolication() || event.stackTrace == null) {
22+
final stackTrace = hint.get(hintRawStackTraceKey) as String?;
23+
if (!event.needsSymbolication() || stackTrace == null) {
2124
return event;
2225
}
2326

2427
final syntheticImage =
25-
_debugImageExtractor.extractDebugImageFrom(event.stackTrace!);
28+
_debugImageExtractor.extractDebugImageFrom(stackTrace);
29+
30+
print(syntheticImage);
2631
if (syntheticImage == null) {
2732
return event;
2833
}

dart/lib/src/protocol/sentry_event.dart

-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import 'package:meta/meta.dart';
22

3-
import '../load_dart_debug_images_integration.dart';
43
import '../protocol.dart';
54
import '../throwable_mechanism.dart';
65
import '../utils.dart';
@@ -40,7 +39,6 @@ class SentryEvent with SentryEventLike<SentryEvent> {
4039
this.debugMeta,
4140
this.type,
4241
this.unknown,
43-
this.stackTrace,
4442
}) : eventId = eventId ?? SentryId.newId(),
4543
timestamp = timestamp ?? getUtcDateTime(),
4644
contexts = contexts ?? Contexts(),
@@ -196,11 +194,6 @@ class SentryEvent with SentryEventLike<SentryEvent> {
196194
@internal
197195
final Map<String, dynamic>? unknown;
198196

199-
/// The stacktrace is only used internally for processing such as in [LoadDartDebugImagesIntegration].
200-
/// TODO: should be a better way than saving a reference to the stacktrace
201-
@internal
202-
final StackTrace? stackTrace;
203-
204197
@override
205198
SentryEvent copyWith({
206199
SentryId? eventId,
@@ -231,7 +224,6 @@ class SentryEvent with SentryEventLike<SentryEvent> {
231224
List<SentryException>? exceptions,
232225
List<SentryThread>? threads,
233226
String? type,
234-
StackTrace? stackTrace,
235227
}) =>
236228
SentryEvent(
237229
eventId: eventId ?? this.eventId,
@@ -265,7 +257,6 @@ class SentryEvent with SentryEventLike<SentryEvent> {
265257
threads: (threads != null ? List.from(threads) : null) ?? this.threads,
266258
type: type ?? this.type,
267259
unknown: unknown,
268-
stackTrace: stackTrace ?? this.stackTrace,
269260
);
270261

271262
/// Deserializes a [SentryEvent] from JSON [Map].

dart/lib/src/protocol/sentry_transaction.dart

-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ class SentryTransaction extends SentryEvent {
4040
Map<String, SentryMeasurement>? measurements,
4141
Map<String, List<MetricSummary>>? metricSummaries,
4242
SentryTransactionInfo? transactionInfo,
43-
StackTrace? stackTrace,
4443
}) : super(
4544
timestamp: timestamp ?? tracer.endTimestamp,
4645
transaction: transaction ?? tracer.name,
@@ -140,7 +139,6 @@ class SentryTransaction extends SentryEvent {
140139
Map<String, SentryMeasurement>? measurements,
141140
Map<String, List<MetricSummary>>? metricSummaries,
142141
SentryTransactionInfo? transactionInfo,
143-
StackTrace? stackTrace,
144142
}) =>
145143
SentryTransaction(
146144
tracer,
@@ -169,6 +167,5 @@ class SentryTransaction extends SentryEvent {
169167
(metricSummaries != null ? Map.from(metricSummaries) : null) ??
170168
this.metricSummaries,
171169
transactionInfo: transactionInfo ?? this.transactionInfo,
172-
stackTrace: stackTrace ?? this.stackTrace,
173170
);
174171
}

dart/lib/src/sentry_client.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'client_reports/client_report_recorder.dart';
77
import 'client_reports/discard_reason.dart';
88
import 'event_processor.dart';
99
import 'hint.dart';
10+
import 'load_dart_debug_images_integration.dart';
1011
import 'metrics/metric.dart';
1112
import 'metrics/metrics_aggregator.dart';
1213
import 'protocol.dart';
@@ -117,6 +118,7 @@ class SentryClient {
117118
SentryEvent? preparedEvent = _prepareEvent(event, stackTrace: stackTrace);
118119

119120
hint ??= Hint();
121+
hint.set(hintRawStackTraceKey, stackTrace.toString());
120122

121123
if (scope != null) {
122124
preparedEvent = await scope.applyToEvent(preparedEvent, hint);
@@ -207,7 +209,6 @@ class SentryClient {
207209
release: event.release ?? _options.release,
208210
sdk: event.sdk ?? _options.sdk,
209211
platform: event.platform ?? sdkPlatform(_options.platformChecker.isWeb),
210-
stackTrace: StackTrace.fromString(stackTrace.toString()),
211212
);
212213

213214
if (event is SentryTransaction) {

dart/test/debug_image_extractor_test.dart

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ void main() {
1414
});
1515

1616
test('extracts debug image from valid stack trace', () {
17-
final stackTrace = StackTrace.fromString('''
17+
final stackTrace = '''
1818
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1919
build_id: 'b680cb890f9e3c12a24b172d050dec73'
2020
isolate_dso_base: 10000000
21-
''');
21+
''';
2222
final extractor = fixture.getSut(platform: MockPlatform.android());
2323
final debugImage = extractor.extractDebugImageFrom(stackTrace);
2424

@@ -28,19 +28,19 @@ isolate_dso_base: 10000000
2828
});
2929

3030
test('returns null for invalid stack trace', () {
31-
final stackTrace = StackTrace.fromString('Invalid stack trace');
31+
final stackTrace = 'Invalid stack trace';
3232
final extractor = fixture.getSut(platform: MockPlatform.android());
3333
final debugImage = extractor.extractDebugImageFrom(stackTrace);
3434

3535
expect(debugImage, isNull);
3636
});
3737

3838
test('extracts correct debug ID for Android', () {
39-
final stackTrace = StackTrace.fromString('''
39+
final stackTrace = '''
4040
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
4141
build_id: 'b680cb890f9e3c12a24b172d050dec73'
4242
isolate_dso_base: 20000000
43-
''');
43+
''';
4444
final extractor = fixture.getSut(platform: MockPlatform.android());
4545
final debugImage = extractor.extractDebugImageFrom(stackTrace);
4646

@@ -49,11 +49,11 @@ isolate_dso_base: 20000000
4949
});
5050

5151
test('extracts correct debug ID for iOS', () {
52-
final stackTrace = StackTrace.fromString('''
52+
final stackTrace = '''
5353
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
5454
build_id: 'b680cb890f9e3c12a24b172d050dec73'
5555
isolate_dso_base: 30000000
56-
''');
56+
''';
5757
final extractor = fixture.getSut(platform: MockPlatform.iOS());
5858
final debugImage = extractor.extractDebugImageFrom(stackTrace);
5959

@@ -63,11 +63,11 @@ isolate_dso_base: 30000000
6363
});
6464

6565
test('sets correct type based on platform', () {
66-
final stackTrace = StackTrace.fromString('''
66+
final stackTrace = '''
6767
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
6868
build_id: 'b680cb890f9e3c12a24b172d050dec73'
6969
isolate_dso_base: 40000000
70-
''');
70+
''';
7171
final androidExtractor = fixture.getSut(platform: MockPlatform.android());
7272
final iosExtractor = fixture.getSut(platform: MockPlatform.iOS());
7373

dart/test/load_dart_debug_images_integration_test.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,16 @@ void main() {
4848

4949
test('Event processor adds debug image when symbolication is needed',
5050
() async {
51-
final stackTrace = StackTrace.fromString('''
51+
final stackTrace = '''
5252
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
5353
build_id: 'b680cb890f9e3c12a24b172d050dec73'
5454
isolate_dso_base: 10000000
55-
''');
55+
''';
5656
SentryEvent event = _getEvent();
57-
event = event.copyWith(stackTrace: stackTrace);
5857

5958
final processor = fixture.options.eventProcessors.first;
60-
final resultEvent = await processor.apply(event, Hint());
59+
final resultEvent = await processor.apply(
60+
event, Hint()..set(hintRawStackTraceKey, stackTrace));
6161

6262
expect(resultEvent?.debugMeta?.images.length, 1);
6363
final debugImage = resultEvent?.debugMeta?.images.first;

flutter/test/mocks.mocks.dart

+6-46
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,6 @@ class MockSentryTracer extends _i1.Mock implements _i4.SentryTracer {
263263
returnValueForMissingStub: null,
264264
);
265265

266-
@override
267-
Map<String, _i2.SentryMeasurement> get measurements => (super.noSuchMethod(
268-
Invocation.getter(#measurements),
269-
returnValue: <String, _i2.SentryMeasurement>{},
270-
) as Map<String, _i2.SentryMeasurement>);
271-
272266
@override
273267
_i2.SentrySpanContext get context => (super.noSuchMethod(
274268
Invocation.getter(#context),
@@ -338,6 +332,12 @@ class MockSentryTracer extends _i1.Mock implements _i4.SentryTracer {
338332
returnValue: <String, String>{},
339333
) as Map<String, String>);
340334

335+
@override
336+
Map<String, _i2.SentryMeasurement> get measurements => (super.noSuchMethod(
337+
Invocation.getter(#measurements),
338+
returnValue: <String, _i2.SentryMeasurement>{},
339+
) as Map<String, _i2.SentryMeasurement>);
340+
341341
@override
342342
_i8.Future<void> finish({
343343
_i3.SpanStatus? status,
@@ -502,24 +502,6 @@ class MockSentryTracer extends _i1.Mock implements _i4.SentryTracer {
502502
returnValueForMissingStub: null,
503503
);
504504

505-
@override
506-
void setMeasurementFromChild(
507-
String? name,
508-
num? value, {
509-
_i2.SentryMeasurementUnit? unit,
510-
}) =>
511-
super.noSuchMethod(
512-
Invocation.method(
513-
#setMeasurementFromChild,
514-
[
515-
name,
516-
value,
517-
],
518-
{#unit: unit},
519-
),
520-
returnValueForMissingStub: null,
521-
);
522-
523505
@override
524506
void scheduleFinish() => super.noSuchMethod(
525507
Invocation.method(
@@ -687,7 +669,6 @@ class MockSentryTransaction extends _i1.Mock implements _i3.SentryTransaction {
687669
Map<String, _i2.SentryMeasurement>? measurements,
688670
Map<String, List<_i3.MetricSummary>>? metricSummaries,
689671
_i3.SentryTransactionInfo? transactionInfo,
690-
StackTrace? stackTrace,
691672
}) =>
692673
(super.noSuchMethod(
693674
Invocation.method(
@@ -723,7 +704,6 @@ class MockSentryTransaction extends _i1.Mock implements _i3.SentryTransaction {
723704
#measurements: measurements,
724705
#metricSummaries: metricSummaries,
725706
#transactionInfo: transactionInfo,
726-
#stackTrace: stackTrace,
727707
},
728708
),
729709
returnValue: _FakeSentryTransaction_7(
@@ -761,20 +741,10 @@ class MockSentryTransaction extends _i1.Mock implements _i3.SentryTransaction {
761741
#measurements: measurements,
762742
#metricSummaries: metricSummaries,
763743
#transactionInfo: transactionInfo,
764-
#stackTrace: stackTrace,
765744
},
766745
),
767746
),
768747
) as _i3.SentryTransaction);
769-
770-
@override
771-
bool needsSymbolication() => (super.noSuchMethod(
772-
Invocation.method(
773-
#needsSymbolication,
774-
[],
775-
),
776-
returnValue: false,
777-
) as bool);
778748
}
779749

780750
/// A class which mocks [SentrySpan].
@@ -1376,16 +1346,6 @@ class MockSentryNativeBinding extends _i1.Mock
13761346
returnValue: _i8.Future<void>.value(),
13771347
returnValueForMissingStub: _i8.Future<void>.value(),
13781348
) as _i8.Future<void>);
1379-
1380-
@override
1381-
_i8.Future<void> nativeCrash() => (super.noSuchMethod(
1382-
Invocation.method(
1383-
#nativeCrash,
1384-
[],
1385-
),
1386-
returnValue: _i8.Future<void>.value(),
1387-
returnValueForMissingStub: _i8.Future<void>.value(),
1388-
) as _i8.Future<void>);
13891349
}
13901350

13911351
/// A class which mocks [Hub].

0 commit comments

Comments
 (0)