Skip to content

Commit 3ec90b4

Browse files
authored
Merge pull request #1233 from Instabug/dev
2 parents 4a36f98 + 1ed8bf1 commit 3ec90b4

33 files changed

+473
-103
lines changed

CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## [13.1.1](https://github.com/Instabug/Instabug-React-Native/compare/v13.0.4...dev) (JUN 6, 2024)
4+
5+
### Fixed
6+
7+
- Reading INSTABUG_APP_TOKEN from system environment when there is no default value ([#1232](https://github.com/Instabug/Instabug-React-Native/pull/1232))
8+
9+
### Changed
10+
11+
- Bump Instabug iOS SDK to v13.1.0 ([#1227](https://github.com/Instabug/Instabug-React-Native/pull/1227)). [See release notes](https://github.com/Instabug/Instabug-iOS/releases/tag/13.1.0).
12+
- Bump Instabug android SDK to v13.1.1 ([#1228](https://github.com/Instabug/Instabug-React-Native/pull/1228)). [See release notes](https://github.com/Instabug/android/releases/tag/v13.1.0).
13+
14+
### Added
15+
16+
- Add support for passing a grouping fingerprint, error level, and user attributes to the `CrashReporting.reportError` non-fatals API ([#1194](https://github.com/Instabug/Instabug-React-Native/pull/1194)).
17+
318
## [13.0.5](https://github.com/Instabug/Instabug-React-Native/compare/v13.0.4...v13.0.5) (May 18, 2024)
419

520
### Changed
@@ -26,7 +41,7 @@
2641
- Bump Instabug iOS SDK to v13.0.0 ([#1189](https://github.com/Instabug/Instabug-React-Native/pull/1189)). [See release notes](https://github.com/instabug/instabug-ios/releases/tag/13.0.0).
2742
- Bump Instabug Android SDK to v13.0.0 ([#1188](https://github.com/Instabug/Instabug-React-Native/pull/1188)). [See release notes](https://github.com/Instabug/android/releases/tag/v13.0.0).
2843

29-
## [12.9.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.8.0...v12.9.0) (April 2, 2024)
44+
## [12.9.0](https://github.com/Instabug/Instabug-React-Native/compare/v12.8.0...12.9.0)(April 2, 2024)
3045

3146
### Added
3247

android/native.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
project.ext.instabug = [
2-
version: '13.0.3'
2+
version: '13.1.1'
33
]
44

55
dependencies {

android/sourcemaps.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ String resolveVar(String name, String envKey, String defaultValue) {
9191
def env = System.getenv()
9292
def envValue = env.get(envKey)
9393

94-
if (envValue != null && envValue != defaultValue) {
94+
if (envValue != null && defaultValue !=null && envValue != defaultValue) {
9595
project.logger.warn "Environment variable `${envKey}` might have incorrect value, " +
9696
"make sure this was intentional:\n" +
9797
" Environment Value: ${envValue}\n" +

android/src/main/java/com/instabug/reactlibrary/ArgsRegistry.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.instabug.bug.BugReporting;
66
import com.instabug.bug.invocation.Option;
7+
import com.instabug.crash.models.IBGNonFatalException;
78
import com.instabug.featuresrequest.ActionType;
89
import com.instabug.library.InstabugColorTheme;
910
import com.instabug.library.InstabugCustomTextPlaceHolder.Key;
@@ -54,11 +55,19 @@ static Map<String, Object> getAll() {
5455
putAll(extendedBugReportStates);
5556
putAll(reproModes);
5657
putAll(sdkLogLevels);
58+
putAll(nonFatalExceptionLevel);
5759
putAll(locales);
5860
putAll(placeholders);
5961
}};
6062
}
6163

64+
public static ArgsMap<IBGNonFatalException.Level> nonFatalExceptionLevel = new ArgsMap<IBGNonFatalException.Level>() {{
65+
put("nonFatalErrorLevelCritical", IBGNonFatalException.Level.CRITICAL);
66+
put("nonFatalErrorLevelError", IBGNonFatalException.Level.ERROR);
67+
put("nonFatalErrorLevelWarning", IBGNonFatalException.Level.WARNING);
68+
put("nonFatalErrorLevelInfo", IBGNonFatalException.Level.INFO);
69+
}};
70+
6271
static ArgsMap<InstabugInvocationEvent> invocationEvents = new ArgsMap<InstabugInvocationEvent>() {{
6372
put("invocationEventNone", InstabugInvocationEvent.NONE);
6473
put("invocationEventShake", InstabugInvocationEvent.SHAKE);

android/src/main/java/com/instabug/reactlibrary/RNInstabugCrashReportingModule.java

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,24 @@
22

33
import static com.instabug.reactlibrary.utils.InstabugUtil.getMethod;
44

5+
import androidx.annotation.NonNull;
6+
57
import com.facebook.react.bridge.Promise;
68
import com.facebook.react.bridge.ReactApplicationContext;
79
import com.facebook.react.bridge.ReactContextBaseJavaModule;
810
import com.facebook.react.bridge.ReactMethod;
11+
import com.facebook.react.bridge.ReadableMap;
912
import com.instabug.crash.CrashReporting;
13+
import com.instabug.crash.models.IBGNonFatalException;
1014
import com.instabug.library.Feature;
1115
import com.instabug.reactlibrary.utils.MainThreadHandler;
1216

1317
import org.json.JSONObject;
1418

1519
import java.lang.reflect.InvocationTargetException;
1620
import java.lang.reflect.Method;
21+
import java.util.HashMap;
22+
import java.util.Map;
1723

1824
import javax.annotation.Nonnull;
1925
import javax.annotation.Nullable;
@@ -57,8 +63,8 @@ public void run() {
5763
* Send unhandled JS error object
5864
*
5965
* @param exceptionObject Exception object to be sent to Instabug's servers
60-
* @param promise This makes sure that the RN side crashes the app only after the Android SDK
61-
* finishes processing/handling the crash.
66+
* @param promise This makes sure that the RN side crashes the app only after the Android SDK
67+
* finishes processing/handling the crash.
6268
*/
6369
@ReactMethod
6470
public void sendJSCrash(final String exceptionObject, final Promise promise) {
@@ -79,41 +85,64 @@ public void run() {
7985
* Send handled JS error object
8086
*
8187
* @param exceptionObject Exception object to be sent to Instabug's servers
88+
* @param userAttributes (Optional) extra user attributes attached to the crash
89+
* @param fingerprint (Optional) key used to customize how crashes are grouped together
90+
* @param level different severity levels for errors
8291
*/
8392
@ReactMethod
84-
public void sendHandledJSCrash(final String exceptionObject) {
93+
public void sendHandledJSCrash(final String exceptionObject, @Nullable ReadableMap userAttributes, @Nullable String fingerprint, @Nullable String level) {
8594
try {
8695
JSONObject jsonObject = new JSONObject(exceptionObject);
87-
sendJSCrashByReflection(jsonObject, true, null);
88-
} catch (Exception e) {
96+
MainThreadHandler.runOnMainThread(new Runnable() {
97+
@Override
98+
public void run() {
99+
try {
100+
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class,
101+
Map.class, JSONObject.class, IBGNonFatalException.Level.class);
102+
if (method != null) {
103+
IBGNonFatalException.Level nonFatalExceptionLevel = ArgsRegistry.nonFatalExceptionLevel.getOrDefault(level, IBGNonFatalException.Level.ERROR);
104+
Map<String, Object> userAttributesMap = userAttributes == null ? null : userAttributes.toHashMap();
105+
JSONObject fingerprintObj = fingerprint == null ? null : CrashReporting.getFingerprintObject(fingerprint);
106+
107+
method.invoke(null, jsonObject, true, userAttributesMap, fingerprintObj, nonFatalExceptionLevel);
108+
109+
RNInstabugReactnativeModule.clearCurrentReport();
110+
}
111+
} catch (ClassNotFoundException | IllegalAccessException |
112+
InvocationTargetException e) {
113+
e.printStackTrace();
114+
}
115+
}
116+
});
117+
} catch (Throwable e) {
89118
e.printStackTrace();
90119
}
91120
}
92121

93-
private void sendJSCrashByReflection(final JSONObject exceptionObject, final boolean isHandled, @Nullable final Runnable onComplete) {
94-
MainThreadHandler.runOnMainThread(new Runnable() {
95-
@Override
96-
public void run() {
97-
try {
98-
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
99-
if (method != null) {
100-
method.invoke(null, exceptionObject, isHandled);
101-
RNInstabugReactnativeModule.clearCurrentReport();
102-
}
103-
} catch (ClassNotFoundException e) {
104-
e.printStackTrace();
105-
} catch (IllegalAccessException e) {
106-
e.printStackTrace();
107-
} catch (InvocationTargetException e) {
108-
e.printStackTrace();
109-
} finally {
110-
if (onComplete != null) {
111-
onComplete.run();
112-
}
113-
}
114-
}
115-
});
116-
}
122+
private void sendJSCrashByReflection(final JSONObject exceptionObject, final boolean isHandled, @Nullable final Runnable onComplete) {
123+
MainThreadHandler.runOnMainThread(new Runnable() {
124+
@Override
125+
public void run() {
126+
try {
127+
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
128+
if (method != null) {
129+
method.invoke(null, exceptionObject, isHandled);
130+
RNInstabugReactnativeModule.clearCurrentReport();
131+
}
132+
} catch (ClassNotFoundException e) {
133+
e.printStackTrace();
134+
} catch (IllegalAccessException e) {
135+
e.printStackTrace();
136+
} catch (InvocationTargetException e) {
137+
e.printStackTrace();
138+
} finally {
139+
if (onComplete != null) {
140+
onComplete.run();
141+
}
142+
}
143+
}
144+
});
145+
}
117146

118147
/**
119148
* Enables and disables capturing native C++ NDK crash reporting.

android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,4 @@ public static Report createReport(ReadableArray tags, ReadableArray consoleLogs,
6464
return report;
6565
}
6666

67-
public static WritableArray parseConsoleLogs(ArrayList<a> consoleLogs) {
68-
WritableArray writableArray = new WritableNativeArray();
69-
70-
for(int i = 0; i < consoleLogs.size(); i++) {
71-
try {
72-
writableArray.pushString(consoleLogs.get(i).toJson());
73-
} catch (Exception e) {
74-
e.printStackTrace();
75-
}
76-
77-
}
78-
79-
return writableArray;
80-
}
8167
}

android/src/test/java/com/instabug/reactlibrary/RNInstabugCrashReportingModuleTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
package com.instabug.reactlibrary;
22

3+
import static com.instabug.crash.CrashReporting.getFingerprintObject;
4+
import static com.instabug.reactlibrary.util.GlobalMocks.reflected;
5+
import static org.mockito.AdditionalMatchers.cmpEq;
36
import static org.mockito.ArgumentMatchers.any;
7+
import static org.mockito.ArgumentMatchers.eq;
8+
import static org.mockito.ArgumentMatchers.same;
49
import static org.mockito.Mockito.mock;
510
import static org.mockito.Mockito.mockStatic;
611

712
import android.os.Looper;
813

914
import com.instabug.crash.CrashReporting;
15+
import com.instabug.crash.models.IBGNonFatalException;
1016
import com.instabug.library.Feature;
1117
import com.instabug.reactlibrary.util.GlobalMocks;
18+
import com.instabug.reactlibrary.util.MockReflected;
1219
import com.instabug.reactlibrary.utils.MainThreadHandler;
1320

21+
import org.json.JSONException;
22+
import org.json.JSONObject;
1423
import org.junit.After;
1524
import org.junit.Before;
1625
import org.junit.Test;
@@ -19,6 +28,9 @@
1928
import org.mockito.invocation.InvocationOnMock;
2029
import org.mockito.stubbing.Answer;
2130

31+
import java.util.HashMap;
32+
import java.util.Map;
33+
2234

2335
public class RNInstabugCrashReportingModuleTest {
2436
private final RNInstabugCrashReportingModule rnModule = new RNInstabugCrashReportingModule(null);
@@ -38,6 +50,7 @@ public void mockMainThreadHandler() throws Exception {
3850
// Mock Looper class
3951
Looper mockMainThreadLooper = mock(Looper.class);
4052
Mockito.when(Looper.getMainLooper()).thenReturn(mockMainThreadLooper);
53+
GlobalMocks.setUp();
4154

4255

4356
// Override runOnMainThread
@@ -58,6 +71,8 @@ public void tearDown() {
5871
mockLooper.close();
5972
mockMainThreadHandler.close();
6073
mockCrashReporting.close();
74+
GlobalMocks.close();
75+
6176
}
6277

6378
/********Crashes*********/
@@ -80,6 +95,18 @@ public void testSetNDKCrashesEnabledGivenFalse() {
8095
mockCrashReporting.verify(() -> CrashReporting.setNDKCrashesState(Feature.State.DISABLED));
8196
}
8297

98+
@Test
99+
public void testSendNonFatalError() {
100+
String jsonCrash = "{}";
101+
boolean isHandled = true;
102+
String fingerPrint = "test";
103+
String level = ArgsRegistry.nonFatalExceptionLevel.keySet().iterator().next();
104+
JSONObject expectedFingerprint = getFingerprintObject(fingerPrint);
105+
IBGNonFatalException.Level expectedLevel = ArgsRegistry.nonFatalExceptionLevel.get(level);
106+
rnModule.sendHandledJSCrash(jsonCrash, null, fingerPrint, level);
107+
reflected.verify(() -> MockReflected.reportException(any(JSONObject.class), eq(isHandled), eq(null), eq(expectedFingerprint), eq(expectedLevel)));
108+
}
109+
83110
@Test
84111
public void givenString$sendHandledJSCrash_whenQuery_thenShouldCallNativeApiWithArgs() throws Exception {
85112
// JSONObject json = mock(JSONObject.class);

android/src/test/java/com/instabug/reactlibrary/util/GlobalMocks.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
import android.util.Log;
66

7+
import com.instabug.crash.models.IBGNonFatalException;
78
import com.instabug.reactlibrary.utils.InstabugUtil;
89

10+
import org.json.JSONObject;
911
import org.mockito.MockedStatic;
1012

1113
import java.lang.reflect.Method;
@@ -37,6 +39,14 @@ public static void setUp() throws NoSuchMethodException {
3739
reflection
3840
.when(() -> InstabugUtil.getMethod(Class.forName("com.instabug.library.util.InstabugDeprecationLogger"), "setBaseUrl", String.class))
3941
.thenReturn(mSetBaseUrl);
42+
43+
// reportException mock
44+
Method mCrashReportException = MockReflected.class.getDeclaredMethod("reportException", JSONObject.class, boolean.class, java.util.Map.class, JSONObject.class, IBGNonFatalException.Level.class);
45+
mCrashReportException.setAccessible(true);
46+
reflection
47+
.when(() -> InstabugUtil.getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class,
48+
boolean.class, java.util.Map.class, JSONObject.class, IBGNonFatalException.Level.class))
49+
.thenReturn(mCrashReportException);
4050
}
4151

4252
public static void close() {

android/src/test/java/com/instabug/reactlibrary/util/MockReflected.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package com.instabug.reactlibrary.util;
22

3+
import com.instabug.crash.models.IBGNonFatalException;
4+
5+
import org.json.JSONObject;
6+
7+
import java.util.Map;
8+
39
/**
410
* Includes fake implementations of methods called by reflection.
511
* Used to verify whether or not a private methods was called.
@@ -16,4 +22,9 @@ public static void setCurrentPlatform(int platform) {}
1622
* Instabug.util.InstabugDeprecationLogger.setBaseUrl
1723
*/
1824
public static void setBaseUrl(String baseUrl) {}
25+
/**
26+
* CrashReporting.reportException
27+
*/
28+
public static void reportException(JSONObject exception, boolean isHandled, Map userAttributes, JSONObject fingerPrint, IBGNonFatalException.Level level) {}
29+
1930
}

0 commit comments

Comments
 (0)