Skip to content

Commit df9c16e

Browse files
committed
Add caching
1 parent 34c4e11 commit df9c16e

File tree

7 files changed

+102
-54
lines changed

7 files changed

+102
-54
lines changed
Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,48 @@
1+
import 'dart:io';
2+
3+
import 'package:http/http.dart';
4+
import 'dart:async';
5+
16
import '../sentry.dart';
27

38
class DartExceptionTypeIdentifier implements ExceptionTypeIdentifier {
49
@override
5-
String? identifyType(dynamic error) {
6-
if (error is ArgumentError) return 'ArgumentError';
7-
if (error is AssertionError) return 'AssertionError';
8-
if (error is ConcurrentModificationError)
10+
String? identifyType(dynamic throwable) {
11+
// dart:core
12+
if (throwable is ArgumentError) return 'ArgumentError';
13+
if (throwable is AssertionError) return 'AssertionError';
14+
if (throwable is ConcurrentModificationError)
915
return 'ConcurrentModificationError';
10-
if (error is FormatException) return 'FormatException';
11-
if (error is IndexError) return 'IndexError';
12-
if (error is NoSuchMethodError) return 'NoSuchMethodError';
13-
if (error is OutOfMemoryError) return 'OutOfMemoryError';
14-
if (error is RangeError) return 'RangeError';
15-
if (error is StackOverflowError) return 'StackOverflowError';
16-
if (error is StateError) return 'StateError';
17-
if (error is TypeError) return 'TypeError';
18-
if (error is UnimplementedError) return 'UnimplementedError';
19-
if (error is UnsupportedError) return 'UnsupportedError';
20-
// we purposefully don't include Exception or Error since it's too generic
16+
if (throwable is FormatException) return 'FormatException';
17+
if (throwable is IndexError) return 'IndexError';
18+
if (throwable is NoSuchMethodError) return 'NoSuchMethodError';
19+
if (throwable is OutOfMemoryError) return 'OutOfMemoryError';
20+
if (throwable is RangeError) return 'RangeError';
21+
if (throwable is StackOverflowError) return 'StackOverflowError';
22+
if (throwable is StateError) return 'StateError';
23+
if (throwable is TypeError) return 'TypeError';
24+
if (throwable is UnimplementedError) return 'UnimplementedError';
25+
if (throwable is UnsupportedError) return 'UnsupportedError';
26+
// not adding Exception or Error because it's too generic
27+
28+
// dart:async
29+
if (throwable is TimeoutException) return 'TimeoutException';
30+
if (throwable is AsyncError) return 'FutureTimeout';
31+
if (throwable is DeferredLoadException) return 'DeferredLoadException';
32+
// not adding ParallelWaitError because it's not supported in dart 2.17.0
33+
34+
// dart:io
35+
if (throwable is FileSystemException) return 'FileSystemException';
36+
if (throwable is HttpException) return 'HttpException';
37+
if (throwable is SocketException) return 'SocketException';
38+
if (throwable is HandshakeException) return 'HandshakeException';
39+
if (throwable is CertificateException) return 'CertificateException';
40+
if (throwable is TlsException) return 'TlsException';
41+
// not adding IOException because it's too generic
42+
43+
// dart http package
44+
if (throwable is ClientException) return 'ClientException';
45+
2146
return null;
2247
}
2348
}

dart/lib/src/exception_type_identifier.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,30 @@
2121
abstract class ExceptionTypeIdentifier {
2222
String? identifyType(dynamic throwable);
2323
}
24+
25+
extension CacheableExceptionIdentifier on ExceptionTypeIdentifier {
26+
ExceptionTypeIdentifier withCache() => _CachingExceptionTypeIdentifier(this);
27+
}
28+
29+
class _CachingExceptionTypeIdentifier implements ExceptionTypeIdentifier {
30+
final ExceptionTypeIdentifier _identifier;
31+
final Map<Type, String?> _knownExceptionTypes = {};
32+
33+
_CachingExceptionTypeIdentifier(this._identifier);
34+
35+
@override
36+
String? identifyType(dynamic throwable) {
37+
final runtimeType = throwable.runtimeType;
38+
if (_knownExceptionTypes.containsKey(runtimeType)) {
39+
return _knownExceptionTypes[runtimeType];
40+
}
41+
42+
final identifiedType = _identifier.identifyType(throwable);
43+
44+
if (identifiedType != null) {
45+
_knownExceptionTypes[runtimeType] = identifiedType;
46+
}
47+
48+
return identifiedType;
49+
}
50+
}

dart/lib/src/sentry.dart

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

33
import 'package:meta/meta.dart';
44

5+
import 'dart_exception_type_identifier.dart';
56
import 'metrics/metrics_api.dart';
67
import 'run_zoned_guarded_integration.dart';
78
import 'event_processor/enricher/enricher_event_processor.dart';
@@ -85,6 +86,8 @@ class Sentry {
8586
options.addEventProcessor(EnricherEventProcessor(options));
8687
options.addEventProcessor(ExceptionEventProcessor(options));
8788
options.addEventProcessor(DeduplicationEventProcessor(options));
89+
90+
options.addExceptionTypeIdentifier(DartExceptionTypeIdentifier());
8891
}
8992

9093
/// This method reads available environment variables and uses them

dart/lib/src/sentry_options.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,16 +437,20 @@ class SentryOptions {
437437
/// Settings this to `false` will set the `level` to [SentryLevel.error].
438438
bool markAutomaticallyCollectedErrorsAsFatal = true;
439439

440-
final List<ExceptionTypeIdentifier> _exceptionTypeIdentifiers = [
441-
DartExceptionTypeIdentifier(),
442-
];
440+
final List<ExceptionTypeIdentifier> _exceptionTypeIdentifiers = [];
443441

444442
List<ExceptionTypeIdentifier> get exceptionTypeIdentifiers =>
445443
_exceptionTypeIdentifiers;
446444

445+
void addExceptionTypeIdentifierByIndex(
446+
int index, ExceptionTypeIdentifier exceptionTypeIdentifier) {
447+
_exceptionTypeIdentifiers.insert(
448+
index, exceptionTypeIdentifier.withCache());
449+
}
450+
447451
void addExceptionTypeIdentifier(
448452
ExceptionTypeIdentifier exceptionTypeIdentifier) {
449-
_exceptionTypeIdentifiers.insert(0, exceptionTypeIdentifier);
453+
_exceptionTypeIdentifiers.add(exceptionTypeIdentifier.withCache());
450454
}
451455

452456
/// The Spotlight configuration.

flutter/lib/src/flutter_error_type_identifier.dart

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'package:flutter/cupertino.dart';
2+
import 'package:flutter/services.dart';
3+
4+
import '../sentry_flutter.dart';
5+
6+
class FlutterExceptionTypeIdentifier implements ExceptionTypeIdentifier {
7+
@override
8+
String? identifyType(dynamic throwable) {
9+
// FlutterError check should run before AssertionError check because
10+
// it's a subclass of AssertionError
11+
if (throwable is FlutterError) return 'FlutterError';
12+
if (throwable is PlatformException) return 'PlatformException';
13+
if (throwable is MissingPluginException) return 'MissingPluginException';
14+
if (throwable is NetworkImageLoadException)
15+
return 'NetworkImageLoadException';
16+
if (throwable is TickerCanceled) return 'TickerCanceled';
17+
return null;
18+
}
19+
}

flutter/lib/src/sentry_flutter.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import 'event_processor/flutter_exception_event_processor.dart';
1111
import 'event_processor/platform_exception_event_processor.dart';
1212
import 'event_processor/widget_event_processor.dart';
1313
import 'file_system_transport.dart';
14-
import 'flutter_error_type_identifier.dart';
14+
import 'flutter_exception_type_identifier.dart';
1515
import 'frame_callback_handler.dart';
1616
import 'integrations/connectivity/connectivity_integration.dart';
1717
import 'integrations/integrations.dart';
@@ -137,7 +137,10 @@ mixin SentryFlutter {
137137

138138
options.addPerformanceCollector(SpanFrameMetricsCollector(options));
139139

140-
options.addExceptionTypeIdentifier(FlutterExceptionTypeIdentifier());
140+
// Insert it before the Dart Exceptions that are set in Sentry.init
141+
// so we can identify Flutter exceptions first.
142+
options.addExceptionTypeIdentifierByIndex(
143+
0, FlutterExceptionTypeIdentifier());
141144

142145
_setSdk(options);
143146
}

0 commit comments

Comments
 (0)