Skip to content

Commit

Permalink
Merge pull request #1233 from Instabug/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
mzelzoghbi authored Jun 6, 2024
2 parents 4a36f98 + 1ed8bf1 commit 3ec90b4
Show file tree
Hide file tree
Showing 33 changed files with 473 additions and 103 deletions.
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [13.1.1](https://github.com/Instabug/Instabug-React-Native/compare/v13.0.4...dev) (JUN 6, 2024)

### Fixed

- Reading INSTABUG_APP_TOKEN from system environment when there is no default value ([#1232](https://github.com/Instabug/Instabug-React-Native/pull/1232))

### Changed

- 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).
- 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).

### Added

- 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)).

## [13.0.5](https://github.com/Instabug/Instabug-React-Native/compare/v13.0.4...v13.0.5) (May 18, 2024)

### Changed
Expand All @@ -26,7 +41,7 @@
- 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).
- 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).

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

### Added

Expand Down
2 changes: 1 addition & 1 deletion android/native.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
project.ext.instabug = [
version: '13.0.3'
version: '13.1.1'
]

dependencies {
Expand Down
2 changes: 1 addition & 1 deletion android/sourcemaps.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ String resolveVar(String name, String envKey, String defaultValue) {
def env = System.getenv()
def envValue = env.get(envKey)

if (envValue != null && envValue != defaultValue) {
if (envValue != null && defaultValue !=null && envValue != defaultValue) {
project.logger.warn "Environment variable `${envKey}` might have incorrect value, " +
"make sure this was intentional:\n" +
" Environment Value: ${envValue}\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.instabug.bug.BugReporting;
import com.instabug.bug.invocation.Option;
import com.instabug.crash.models.IBGNonFatalException;
import com.instabug.featuresrequest.ActionType;
import com.instabug.library.InstabugColorTheme;
import com.instabug.library.InstabugCustomTextPlaceHolder.Key;
Expand Down Expand Up @@ -54,11 +55,19 @@ static Map<String, Object> getAll() {
putAll(extendedBugReportStates);
putAll(reproModes);
putAll(sdkLogLevels);
putAll(nonFatalExceptionLevel);
putAll(locales);
putAll(placeholders);
}};
}

public static ArgsMap<IBGNonFatalException.Level> nonFatalExceptionLevel = new ArgsMap<IBGNonFatalException.Level>() {{
put("nonFatalErrorLevelCritical", IBGNonFatalException.Level.CRITICAL);
put("nonFatalErrorLevelError", IBGNonFatalException.Level.ERROR);
put("nonFatalErrorLevelWarning", IBGNonFatalException.Level.WARNING);
put("nonFatalErrorLevelInfo", IBGNonFatalException.Level.INFO);
}};

static ArgsMap<InstabugInvocationEvent> invocationEvents = new ArgsMap<InstabugInvocationEvent>() {{
put("invocationEventNone", InstabugInvocationEvent.NONE);
put("invocationEventShake", InstabugInvocationEvent.SHAKE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@

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

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.instabug.crash.CrashReporting;
import com.instabug.crash.models.IBGNonFatalException;
import com.instabug.library.Feature;
import com.instabug.reactlibrary.utils.MainThreadHandler;

import org.json.JSONObject;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -57,8 +63,8 @@ public void run() {
* Send unhandled JS error object
*
* @param exceptionObject Exception object to be sent to Instabug's servers
* @param promise This makes sure that the RN side crashes the app only after the Android SDK
* finishes processing/handling the crash.
* @param promise This makes sure that the RN side crashes the app only after the Android SDK
* finishes processing/handling the crash.
*/
@ReactMethod
public void sendJSCrash(final String exceptionObject, final Promise promise) {
Expand All @@ -79,41 +85,64 @@ public void run() {
* Send handled JS error object
*
* @param exceptionObject Exception object to be sent to Instabug's servers
* @param userAttributes (Optional) extra user attributes attached to the crash
* @param fingerprint (Optional) key used to customize how crashes are grouped together
* @param level different severity levels for errors
*/
@ReactMethod
public void sendHandledJSCrash(final String exceptionObject) {
public void sendHandledJSCrash(final String exceptionObject, @Nullable ReadableMap userAttributes, @Nullable String fingerprint, @Nullable String level) {
try {
JSONObject jsonObject = new JSONObject(exceptionObject);
sendJSCrashByReflection(jsonObject, true, null);
} catch (Exception e) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class,
Map.class, JSONObject.class, IBGNonFatalException.Level.class);
if (method != null) {
IBGNonFatalException.Level nonFatalExceptionLevel = ArgsRegistry.nonFatalExceptionLevel.getOrDefault(level, IBGNonFatalException.Level.ERROR);
Map<String, Object> userAttributesMap = userAttributes == null ? null : userAttributes.toHashMap();
JSONObject fingerprintObj = fingerprint == null ? null : CrashReporting.getFingerprintObject(fingerprint);

method.invoke(null, jsonObject, true, userAttributesMap, fingerprintObj, nonFatalExceptionLevel);

RNInstabugReactnativeModule.clearCurrentReport();
}
} catch (ClassNotFoundException | IllegalAccessException |
InvocationTargetException e) {
e.printStackTrace();
}
}
});
} catch (Throwable e) {
e.printStackTrace();
}
}

private void sendJSCrashByReflection(final JSONObject exceptionObject, final boolean isHandled, @Nullable final Runnable onComplete) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
if (method != null) {
method.invoke(null, exceptionObject, isHandled);
RNInstabugReactnativeModule.clearCurrentReport();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
if (onComplete != null) {
onComplete.run();
}
}
}
});
}
private void sendJSCrashByReflection(final JSONObject exceptionObject, final boolean isHandled, @Nullable final Runnable onComplete) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
if (method != null) {
method.invoke(null, exceptionObject, isHandled);
RNInstabugReactnativeModule.clearCurrentReport();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
if (onComplete != null) {
onComplete.run();
}
}
}
});
}

/**
* Enables and disables capturing native C++ NDK crash reporting.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,4 @@ public static Report createReport(ReadableArray tags, ReadableArray consoleLogs,
return report;
}

public static WritableArray parseConsoleLogs(ArrayList<a> consoleLogs) {
WritableArray writableArray = new WritableNativeArray();

for(int i = 0; i < consoleLogs.size(); i++) {
try {
writableArray.pushString(consoleLogs.get(i).toJson());
} catch (Exception e) {
e.printStackTrace();
}

}

return writableArray;
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package com.instabug.reactlibrary;

import static com.instabug.crash.CrashReporting.getFingerprintObject;
import static com.instabug.reactlibrary.util.GlobalMocks.reflected;
import static org.mockito.AdditionalMatchers.cmpEq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;

import android.os.Looper;

import com.instabug.crash.CrashReporting;
import com.instabug.crash.models.IBGNonFatalException;
import com.instabug.library.Feature;
import com.instabug.reactlibrary.util.GlobalMocks;
import com.instabug.reactlibrary.util.MockReflected;
import com.instabug.reactlibrary.utils.MainThreadHandler;

import org.json.JSONException;
import org.json.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -19,6 +28,9 @@
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.util.HashMap;
import java.util.Map;


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


// Override runOnMainThread
Expand All @@ -58,6 +71,8 @@ public void tearDown() {
mockLooper.close();
mockMainThreadHandler.close();
mockCrashReporting.close();
GlobalMocks.close();

}

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

@Test
public void testSendNonFatalError() {
String jsonCrash = "{}";
boolean isHandled = true;
String fingerPrint = "test";
String level = ArgsRegistry.nonFatalExceptionLevel.keySet().iterator().next();
JSONObject expectedFingerprint = getFingerprintObject(fingerPrint);
IBGNonFatalException.Level expectedLevel = ArgsRegistry.nonFatalExceptionLevel.get(level);
rnModule.sendHandledJSCrash(jsonCrash, null, fingerPrint, level);
reflected.verify(() -> MockReflected.reportException(any(JSONObject.class), eq(isHandled), eq(null), eq(expectedFingerprint), eq(expectedLevel)));
}

@Test
public void givenString$sendHandledJSCrash_whenQuery_thenShouldCallNativeApiWithArgs() throws Exception {
// JSONObject json = mock(JSONObject.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import android.util.Log;

import com.instabug.crash.models.IBGNonFatalException;
import com.instabug.reactlibrary.utils.InstabugUtil;

import org.json.JSONObject;
import org.mockito.MockedStatic;

import java.lang.reflect.Method;
Expand Down Expand Up @@ -37,6 +39,14 @@ public static void setUp() throws NoSuchMethodException {
reflection
.when(() -> InstabugUtil.getMethod(Class.forName("com.instabug.library.util.InstabugDeprecationLogger"), "setBaseUrl", String.class))
.thenReturn(mSetBaseUrl);

// reportException mock
Method mCrashReportException = MockReflected.class.getDeclaredMethod("reportException", JSONObject.class, boolean.class, java.util.Map.class, JSONObject.class, IBGNonFatalException.Level.class);
mCrashReportException.setAccessible(true);
reflection
.when(() -> InstabugUtil.getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class,
boolean.class, java.util.Map.class, JSONObject.class, IBGNonFatalException.Level.class))
.thenReturn(mCrashReportException);
}

public static void close() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package com.instabug.reactlibrary.util;

import com.instabug.crash.models.IBGNonFatalException;

import org.json.JSONObject;

import java.util.Map;

/**
* Includes fake implementations of methods called by reflection.
* Used to verify whether or not a private methods was called.
Expand All @@ -16,4 +22,9 @@ public static void setCurrentPlatform(int platform) {}
* Instabug.util.InstabugDeprecationLogger.setBaseUrl
*/
public static void setBaseUrl(String baseUrl) {}
/**
* CrashReporting.reportException
*/
public static void reportException(JSONObject exception, boolean isHandled, Map userAttributes, JSONObject fingerPrint, IBGNonFatalException.Level level) {}

}
Loading

0 comments on commit 3ec90b4

Please sign in to comment.