11package io .sentry ;
22
3+ import android .content .Context ;
4+ import android .content .pm .PackageInfo ;
5+ import android .content .pm .PackageManager ;
6+ import android .util .Log ;
7+
38import com .facebook .react .ReactApplication ;
49import com .facebook .react .bridge .Arguments ;
510import com .facebook .react .bridge .Promise ;
1015import com .facebook .react .bridge .ReadableNativeArray ;
1116import com .facebook .react .bridge .ReadableNativeMap ;
1217import com .facebook .react .bridge .WritableMap ;
18+ import com .facebook .react .bridge .WritableNativeMap ;
1319
1420import java .util .HashMap ;
1521import java .util .Map ;
@@ -31,14 +37,18 @@ public class RNSentryModule extends ReactContextBaseJavaModule {
3137 private final ReactApplicationContext reactContext ;
3238 private final ReactApplication reactApplication ;
3339
40+ private static AndroidEventBuilderHelper androidHelper ;
41+ private static PackageInfo packageInfo ;
3442 final static Logger logger = Logger .getLogger ("react-native-sentry" );
35- private ReadableMap extra ;
36- private ReadableMap tags ;
43+ private static WritableNativeMap extra ;
44+ private static ReadableMap tags ;
3745
3846 public RNSentryModule (ReactApplicationContext reactContext , ReactApplication reactApplication ) {
3947 super (reactContext );
4048 this .reactContext = reactContext ;
4149 this .reactApplication = reactApplication ;
50+ RNSentryModule .extra = new WritableNativeMap ();
51+ RNSentryModule .packageInfo = getPackageInfo (reactContext );
4252 }
4353
4454 public ReactApplication getReactApplication () {
@@ -60,6 +70,7 @@ public Map<String, Object> getConstants() {
6070 @ ReactMethod
6171 public void startWithDsnString (String dsnString ) {
6272 SentryClient sentryClient = Sentry .init (dsnString , new AndroidSentryClientFactory (this .getReactApplicationContext ()));
73+ androidHelper = new AndroidEventBuilderHelper (this .getReactApplicationContext ());
6374 sentryClient .addEventSendCallback (new EventSendCallback () {
6475 @ Override
6576 public void onFailure (Event event , Exception exception ) {
@@ -84,12 +95,18 @@ public void setLogLevel(int level) {
8495
8596 @ ReactMethod
8697 public void setExtra (ReadableMap extra ) {
87- this .extra = extra ;
98+ RNSentryModule .extra .merge (extra );
99+ }
100+
101+ @ ReactMethod
102+ public void addExtra (String key , String value ) {
103+ RNSentryModule .extra .putString (key , value );
104+ logger .info (String .format ("addExtra '%s' '%s'" , key , value ));
88105 }
89106
90107 @ ReactMethod
91108 public void setTags (ReadableMap tags ) {
92- this .tags = tags ;
109+ RNSentryModule .tags = tags ;
93110 }
94111
95112 @ ReactMethod
@@ -128,7 +145,6 @@ public void captureBreadcrumb(ReadableMap breadcrumb) {
128145 public void captureEvent (ReadableMap event ) {
129146 ReadableNativeMap castEvent = (ReadableNativeMap )event ;
130147 if (event .hasKey ("message" )) {
131- AndroidEventBuilderHelper helper = new AndroidEventBuilderHelper (this .getReactApplicationContext ());
132148 EventBuilder eventBuilder = new EventBuilder ()
133149 .withMessage (event .getString ("message" ))
134150 .withLogger (event .getString ("logger" ))
@@ -144,34 +160,19 @@ public void captureEvent(ReadableMap event) {
144160 eventBuilder .withSentryInterface (userInterface );
145161 }
146162
147- helper .helpBuildingEvent (eventBuilder );
148-
149- if (this .extra != null ) {
150- for (Map .Entry <String , Object > entry : ((ReadableNativeMap )this .extra ).toHashMap ().entrySet ()) {
151- eventBuilder .withExtra (entry .getKey (), entry .getValue ());
152- }
153- }
154-
155163 if (castEvent .hasKey ("extra" )) {
156164 for (Map .Entry <String , Object > entry : castEvent .getMap ("extra" ).toHashMap ().entrySet ()) {
157165 eventBuilder .withExtra (entry .getKey (), entry .getValue ());
158166 }
159167 }
160168
161- if (this .tags != null ) {
162- for (Map .Entry <String , Object > entry : ((ReadableNativeMap )this .tags ).toHashMap ().entrySet ()) {
163- eventBuilder .withExtra (entry .getKey (), entry .getValue ());
164- }
165- }
166-
167169 if (castEvent .hasKey ("tags" )) {
168170 for (Map .Entry <String , Object > entry : castEvent .getMap ("tags" ).toHashMap ().entrySet ()) {
169171 eventBuilder .withTag (entry .getKey (), entry .getValue ().toString ());
170172 }
171173 }
172174
173- Event builtEvent = eventBuilder .build ();
174- Sentry .capture (builtEvent );
175+ Sentry .capture (buildEvent (eventBuilder ));
175176 } else {
176177 RNSentryExceptionsManagerModule .lastReceivedException = event ;
177178 if (this .getReactApplication ().getReactNativeHost ().getUseDeveloperSupport () == true ) {
@@ -186,8 +187,8 @@ public void captureEvent(ReadableMap event) {
186187 @ ReactMethod
187188 public void clearContext () {
188189 Sentry .clearContext ();
189- this .extra = null ;
190- this .tags = null ;
190+ RNSentryModule .extra = new WritableNativeMap () ;
191+ RNSentryModule .tags = null ;
191192 }
192193
193194 @ ReactMethod
@@ -197,6 +198,61 @@ public void activateStacktraceMerging(Promise promise) {
197198 promise .reject ("Sentry" , "Stacktrace merging not yet implemented" );
198199 }
199200
201+ public static Event buildEvent (EventBuilder eventBuilder ) {
202+ androidHelper .helpBuildingEvent (eventBuilder );
203+
204+ setRelease (eventBuilder );
205+ stripInternalSentry (eventBuilder );
206+
207+ if (extra != null ) {
208+ for (Map .Entry <String , Object > entry : extra .toHashMap ().entrySet ()) {
209+ if (entry .getValue () != null ) {
210+ eventBuilder .withExtra (entry .getKey (), entry .getValue ());
211+ logger .info (String .format ("addExtra '%s' '%s'" , entry .getKey (), entry .getValue ()));
212+ }
213+ }
214+ }
215+ if (tags != null ) {
216+ for (Map .Entry <String , Object > entry : ((ReadableNativeMap )tags ).toHashMap ().entrySet ()) {
217+ eventBuilder .withExtra (entry .getKey (), entry .getValue ());
218+ }
219+ }
220+
221+ return eventBuilder .build ();
222+ }
223+
224+ private static void stripInternalSentry (EventBuilder eventBuilder ) {
225+ if (extra != null ) {
226+ for (Map .Entry <String , Object > entry : extra .toHashMap ().entrySet ()) {
227+ if (entry .getKey ().startsWith ("__sentry" )) {
228+ extra .putNull (entry .getKey ());
229+ }
230+ }
231+ }
232+ }
233+
234+ private static void setRelease (EventBuilder eventBuilder ) {
235+ if (extra .hasKey ("__sentry_version" )) {
236+ eventBuilder .withRelease (packageInfo .packageName + "-" + extra .getString ("__sentry_version" ));
237+ eventBuilder .withDist (null );
238+ }
239+ if (extra .hasKey ("__sentry_release" )) {
240+ eventBuilder .withRelease (extra .getString ("__sentry_release" ));
241+ }
242+ if (extra .hasKey ("__sentry_dist" )) {
243+ eventBuilder .withDist (extra .getString ("__sentry_dist" ));
244+ }
245+ }
246+
247+ private static PackageInfo getPackageInfo (Context ctx ) {
248+ try {
249+ return ctx .getPackageManager ().getPackageInfo (ctx .getPackageName (), 0 );
250+ } catch (PackageManager .NameNotFoundException e ) {
251+ logger .info ("Error getting package info." );
252+ return null ;
253+ }
254+ }
255+
200256 private Breadcrumb .Level breadcrumbLevel (String level ) {
201257 switch (level ) {
202258 case "critical" :
0 commit comments