Skip to content

Commit 212d6c7

Browse files
authored
fix: unsupported types with expando (#1690)
* Support string, int, double and bool as throwable for expando * Rename the test file and move it to utils folder{ * Remvoe ffi import * Update changelog * Try other url for dio pubspec doc url * Change doc url of logging pubspec * Remove unnecessary code * Update naming * Rename
1 parent 8a10ab7 commit 212d6c7

File tree

4 files changed

+134
-2
lines changed

4 files changed

+134
-2
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Fixes
6+
7+
- Unsupported types with Expando ([#1690](https://github.com/getsentry/sentry-dart/pull/1690))
8+
59
### Features
610

711
- Breadcrumbs for database operations ([#1656](https://github.com/getsentry/sentry-dart/pull/1656))

dart/lib/src/hub.dart

+36
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,8 @@ class _WeakMap {
605605

606606
final SentryOptions _options;
607607

608+
final throwableHandler = UnsupportedThrowablesHandler();
609+
608610
_WeakMap(this._options);
609611

610612
void add(
@@ -615,6 +617,7 @@ class _WeakMap {
615617
if (throwable == null) {
616618
return;
617619
}
620+
throwable = throwableHandler.wrapIfUnsupportedType(throwable);
618621
try {
619622
if (_expando[throwable] == null) {
620623
_expando[throwable] = MapEntry(span, transaction);
@@ -633,6 +636,7 @@ class _WeakMap {
633636
if (throwable == null) {
634637
return null;
635638
}
639+
throwable = throwableHandler.wrapIfUnsupportedType(throwable);
636640
try {
637641
return _expando[throwable] as MapEntry<ISentrySpan, String>?;
638642
} catch (exception, stackTrace) {
@@ -646,3 +650,35 @@ class _WeakMap {
646650
return null;
647651
}
648652
}
653+
654+
/// A handler for unsupported throwables used for Expando<Object>.
655+
@visibleForTesting
656+
class UnsupportedThrowablesHandler {
657+
final _unsupportedTypes = {String, int, double, bool};
658+
final _unsupportedThrowables = <Object>{};
659+
660+
dynamic wrapIfUnsupportedType(dynamic throwable) {
661+
if (_unsupportedTypes.contains(throwable.runtimeType)) {
662+
throwable = _UnsupportedExceptionWrapper(Exception(throwable));
663+
_unsupportedThrowables.add(throwable);
664+
}
665+
return _unsupportedThrowables.lookup(throwable) ?? throwable;
666+
}
667+
}
668+
669+
class _UnsupportedExceptionWrapper {
670+
_UnsupportedExceptionWrapper(this.exception);
671+
672+
final Exception exception;
673+
674+
@override
675+
bool operator ==(Object other) {
676+
if (other is _UnsupportedExceptionWrapper) {
677+
return other.exception.toString() == exception.toString();
678+
}
679+
return false;
680+
}
681+
682+
@override
683+
int get hashCode => exception.toString().hashCode;
684+
}

dart/test/hub_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ void main() {
150150

151151
final capturedEvent = fixture.client.captureEventCalls.first;
152152

153-
expect(capturedEvent.event.transaction, isNull);
154-
expect(capturedEvent.event.contexts.trace, isNull);
153+
expect(capturedEvent.event.transaction, 'test');
154+
expect(capturedEvent.event.contexts.trace, isNotNull);
155155
});
156156
});
157157

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import 'package:sentry/src/hub.dart';
2+
import 'package:test/expect.dart';
3+
import 'package:test/scaffolding.dart';
4+
5+
void main() {
6+
late Fixture fixture;
7+
8+
setUp(() {
9+
fixture = Fixture();
10+
});
11+
12+
group('unsupported throwable types', () {
13+
test('wrapped string throwable does not throw when expanding', () async {
14+
final throwableHandler = fixture.sut;
15+
final unsupportedThrowable = 'test throwable';
16+
final wrappedThrowable =
17+
throwableHandler.wrapIfUnsupportedType(unsupportedThrowable);
18+
19+
expect(() {
20+
fixture.expando[wrappedThrowable];
21+
}, returnsNormally);
22+
});
23+
24+
test('wrapped int throwable does not throw when expanding', () async {
25+
final throwableHandler = fixture.sut;
26+
final unsupportedThrowable = 1;
27+
final wrappedThrowable =
28+
throwableHandler.wrapIfUnsupportedType(unsupportedThrowable);
29+
30+
expect(() {
31+
fixture.expando[wrappedThrowable];
32+
}, returnsNormally);
33+
});
34+
35+
test('wrapped double throwable does not throw when expanding', () async {
36+
final throwableHandler = fixture.sut;
37+
final unsupportedThrowable = 1.0;
38+
final wrappedThrowable =
39+
throwableHandler.wrapIfUnsupportedType(unsupportedThrowable);
40+
41+
expect(() {
42+
fixture.expando[wrappedThrowable];
43+
}, returnsNormally);
44+
});
45+
46+
test('wrapped bool throwable does not throw when expanding', () async {
47+
final throwableHandler = fixture.sut;
48+
final unsupportedThrowable = true;
49+
final wrappedThrowable =
50+
throwableHandler.wrapIfUnsupportedType(unsupportedThrowable);
51+
52+
expect(() {
53+
fixture.expando[wrappedThrowable];
54+
}, returnsNormally);
55+
});
56+
57+
test(
58+
'creating multiple instances of string wrapped exceptions accesses the same expando value',
59+
() async {
60+
final unsupportedThrowable = 'test throwable';
61+
final throwableHandler = fixture.sut;
62+
63+
final first =
64+
throwableHandler.wrapIfUnsupportedType(unsupportedThrowable);
65+
fixture.expando[first] = 1;
66+
67+
final second =
68+
throwableHandler.wrapIfUnsupportedType(unsupportedThrowable);
69+
expect(fixture.expando[second], 1);
70+
fixture.expando[second] = 2.0;
71+
72+
final third =
73+
throwableHandler.wrapIfUnsupportedType(unsupportedThrowable);
74+
expect(fixture.expando[third], 2.0);
75+
});
76+
});
77+
78+
group('supported throwable type', () {
79+
test('does not wrap exception if it is a supported type', () async {
80+
final supportedThrowable = Exception('test throwable');
81+
final result = fixture.sut.wrapIfUnsupportedType(supportedThrowable);
82+
83+
expect(result, supportedThrowable);
84+
});
85+
});
86+
}
87+
88+
class Fixture {
89+
final expando = Expando();
90+
91+
UnsupportedThrowablesHandler get sut => UnsupportedThrowablesHandler();
92+
}

0 commit comments

Comments
 (0)