Skip to content

feat: enhance non-fatals support #461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
aa9306d
feat: add non fatal api
ahmedAlaaInstabug Apr 21, 2024
af30124
feat:add-non-fatal-api
ahmedAlaaInstabug Apr 21, 2024
047c2a8
feat:add-non-fatal-api
ahmedAlaaInstabug Apr 21, 2024
c006ff4
Merge branch 'dev' into feat/add-non-fatal-api
ahmedAlaaInstabug Apr 28, 2024
8f9f384
fix: conflict issue
ahmedAlaaInstabug Apr 28, 2024
021a4ba
fix: conflict issue
ahmedAlaaInstabug Apr 28, 2024
afe230f
Merge branch 'dev' into feat/add-non-fatal-api
ahmedAlaaInstabug Apr 28, 2024
02380a7
fix: conflict issue
ahmedAlaaInstabug Apr 28, 2024
9cae684
add example app
ahmedAlaaInstabug Apr 29, 2024
6bcee7b
add example app
ahmedAlaaInstabug Apr 29, 2024
a8ebebc
add example app
ahmedAlaaInstabug Apr 29, 2024
259de16
fix: PR comments
ahmedAlaaInstabug Apr 29, 2024
67c3547
Update CHANGELOG.md
ahmedAlaaInstabug Apr 29, 2024
6c6899e
fix: PR comments
ahmedAlaaInstabug Apr 29, 2024
d234c5d
Merge remote-tracking branch 'origin/feat/add-non-fatal-api' into fea…
ahmedAlaaInstabug Apr 29, 2024
38e6afa
fix: syntax error
ahmedAlaaInstabug Apr 29, 2024
3aa8058
fix: syntax error
ahmedAlaaInstabug Apr 29, 2024
9f72aa6
Merge branch 'dev' into feat/add-non-fatal-api
ahmedAlaaInstabug Jun 4, 2024
259a45f
docs: fix changeLog
ahmedAlaaInstabug Jun 4, 2024
eb8fdd4
docs: fix changeLog
ahmedAlaaInstabug Jun 4, 2024
9558d18
Merge branch 'dev' into feat/add-non-fatal-api
ahmedAlaaInstabug Jun 10, 2024
450ae0f
resolve conflict issues
ahmedAlaaInstabug Jun 10, 2024
659267a
fix:ios
ahmedAlaaInstabug Jun 11, 2024
74128a3
fix:ios
ahmedAlaaInstabug Jun 11, 2024
174b90d
fix:ios
ahmedAlaaInstabug Jun 11, 2024
9d8420b
fix:ios
ahmedAlaaInstabug Jun 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ commands:
steps:
- run:
name: Install XCUITest Driver
command: appium driver install xcuitest@7.14.0
command: appium driver install xcuitest@4.35.0
- when:
condition:
equal:
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased](https://github.com/Instabug/Instabug-Flutter/compare/v13.0.0...dev)

### Added
- Add support for passing a grouping fingerprint, error level, and user attributes to the `CrashReporting.reportHandledCrash` non-fatals API ([#461](https://github.com/Instabug/Instabug-Flutter/pull/461)).

### Changed

- Bump Instabug iOS SDK to v13.1.0 ([#1227](https://github.com/Instabug/Instabug-Flutter/pull/1227)). [See release notes](https://github.com/Instabug/Instabug-iOS/releases/tag/13.1.0).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package com.instabug.flutter.modules;

import android.util.Log;
import static com.instabug.crash.CrashReporting.getFingerprintObject;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.instabug.crash.CrashReporting;
import com.instabug.crash.models.IBGNonFatalException;
import com.instabug.flutter.generated.CrashReportingPigeon;
import com.instabug.flutter.util.ArgsRegistry;
import com.instabug.flutter.util.Reflection;
import com.instabug.library.Feature;

import org.json.JSONObject;

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

import io.flutter.plugin.common.BinaryMessenger;

Expand Down Expand Up @@ -46,4 +50,24 @@ public void send(@NonNull String jsonCrash, @NonNull Boolean isHandled) {
}
}

@Override
public void sendNonFatalError(@NonNull String jsonCrash, @Nullable Map<String, String> userAttributes, @Nullable String fingerprint, @NonNull String nonFatalExceptionLevel) {
try {
Method method = Reflection.getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class,
Map.class, JSONObject.class, IBGNonFatalException.Level.class);
final JSONObject exceptionObject = new JSONObject(jsonCrash);

JSONObject fingerprintObj = null;
if (fingerprint != null) {
fingerprintObj = getFingerprintObject(fingerprint);
}
IBGNonFatalException.Level nonFatalExceptionLevelType = ArgsRegistry.nonFatalExceptionLevel.get(nonFatalExceptionLevel);
if (method != null) {
method.invoke(null, exceptionObject, true, userAttributes, fingerprintObj, nonFatalExceptionLevelType);
}
} catch (Exception e) {
e.printStackTrace();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import androidx.annotation.NonNull;

import com.instabug.crash.models.IBGNonFatalException;
import com.instabug.library.LogLevel;
import com.instabug.bug.BugReporting;
import com.instabug.bug.invocation.Option;
Expand Down Expand Up @@ -56,7 +57,12 @@ public T get(Object key) {
put("ColorTheme.light", InstabugColorTheme.InstabugColorThemeLight);
put("ColorTheme.dark", InstabugColorTheme.InstabugColorThemeDark);
}};

public static ArgsMap<IBGNonFatalException.Level> nonFatalExceptionLevel = new ArgsMap<IBGNonFatalException.Level>() {{
put("NonFatalExceptionLevel.critical", IBGNonFatalException.Level.CRITICAL);
put("NonFatalExceptionLevel.error", IBGNonFatalException.Level.ERROR);
put("NonFatalExceptionLevel.warning", IBGNonFatalException.Level.WARNING);
put("NonFatalExceptionLevel.info", IBGNonFatalException.Level.INFO);
}};
public static final ArgsMap<InstabugFloatingButtonEdge> floatingButtonEdges = new ArgsMap<InstabugFloatingButtonEdge>() {{
put("FloatingButtonEdge.left", InstabugFloatingButtonEdge.LEFT);
put("FloatingButtonEdge.right", InstabugFloatingButtonEdge.RIGHT);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.instabug.flutter;

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

import com.instabug.crash.CrashReporting;
import com.instabug.crash.models.IBGNonFatalException;
import com.instabug.flutter.generated.CrashReportingPigeon;
import com.instabug.flutter.modules.CrashReportingApi;
import com.instabug.flutter.util.ArgsRegistry;
import com.instabug.flutter.util.GlobalMocks;
import com.instabug.flutter.util.MockReflected;
import com.instabug.library.Feature;
Expand All @@ -19,6 +22,9 @@
import org.junit.Test;
import org.mockito.MockedStatic;

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

import io.flutter.plugin.common.BinaryMessenger;


Expand Down Expand Up @@ -77,4 +83,19 @@ public void testSend() {

reflected.verify(() -> MockReflected.crashReportException(any(JSONObject.class), eq(isHandled)));
}

@Test
public void testSendNonFatalError() {
String jsonCrash = "{}";
boolean isHandled = true;
String fingerPrint = "test";

Map<String, String> expectedUserAttributes = new HashMap<>();
String level = ArgsRegistry.nonFatalExceptionLevel.keySet().iterator().next();
JSONObject expectedFingerprint = getFingerprintObject(fingerPrint);
IBGNonFatalException.Level expectedLevel = ArgsRegistry.nonFatalExceptionLevel.get(level);
api.sendNonFatalError(jsonCrash, expectedUserAttributes, fingerPrint, level);

reflected.verify(() -> MockReflected.crashReportException(any(JSONObject.class), eq(isHandled), eq(expectedUserAttributes), eq(expectedFingerprint), eq(expectedLevel)));
}
}
12 changes: 12 additions & 0 deletions android/src/test/java/com/instabug/flutter/util/GlobalMocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
import android.net.Uri;
import android.util.Log;

import com.instabug.crash.models.IBGNonFatalException;

import org.json.JSONObject;
import org.mockito.MockedStatic;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

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

public class GlobalMocks {
public static MockedStatic<ThreadManager> threadManager;
Expand Down Expand Up @@ -75,6 +78,15 @@ public static void setUp() throws NoSuchMethodException {
JSONObject.class, boolean.class))
.thenReturn(mCrashReportException);

Method mCrashReportNonFatalException = MockReflected.class.getDeclaredMethod("crashReportException", JSONObject.class, boolean.class,
Map.class, JSONObject.class, IBGNonFatalException.Level.class);
mCrashReportNonFatalException.setAccessible(true);
reflection
.when(() -> Reflection.getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException",
JSONObject.class, boolean.class,
Map.class, JSONObject.class, IBGNonFatalException.Level.class))
.thenReturn(mCrashReportNonFatalException);

uri = mockStatic(Uri.class);
uri.when(() -> Uri.fromFile(any())).thenReturn(mock(Uri.class));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

import androidx.annotation.Nullable;

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 Down Expand Up @@ -36,4 +40,6 @@ public static void apmNetworkLog(long requestStartTime, long requestDuration, St
* CrashReporting.reportException
*/
public static void crashReportException(JSONObject exception, boolean isHandled) {}
public static void crashReportException(JSONObject exception, boolean isHandled, Map<String,String> userAttributes, JSONObject fingerPrint, IBGNonFatalException.Level level) {}

}
2 changes: 1 addition & 1 deletion e2e/BugReportingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void ManualInvocation()
[Fact]
public void MultipleScreenshotsInReproSteps()
{
ScrollDown();
ScrollDownLittle();

captain.FindByText("Enter screen name").Tap();
captain.Type("My Screen");
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
<string>12.0</string>
</dict>
</plist>
37 changes: 30 additions & 7 deletions example/ios/InstabugTests/CrashReportingApiTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
#import "Instabug/IBGCrashReporting.h"
#import "Instabug/Instabug.h"
#import "Util/Instabug+Test.h"
#import "Util/IBGCrashReporting+CP.h"

@interface CrashReportingApiTests : XCTestCase

@property (nonatomic, strong) id mCrashReporting;
@property (nonatomic, strong) id mInstabug;
@property (nonatomic, strong) CrashReportingApi *api;
@property(nonatomic, strong) id mCrashReporting;
@property(nonatomic, strong) id mInstabug;
@property(nonatomic, strong) CrashReportingApi *api;

@end

Expand All @@ -24,20 +25,42 @@ - (void)setUp {
- (void)testSetEnabled {
NSNumber *isEnabled = @1;
FlutterError *error;

[self.api setEnabledIsEnabled:isEnabled error:&error];

OCMVerify([self.mCrashReporting setEnabled:YES]);
}

- (void)testSend {
NSString *jsonCrash = @"{}";
NSNumber *isHandled = @0;
FlutterError *error;

[self.api sendJsonCrash:jsonCrash isHandled:isHandled error:&error];

OCMVerify([self.mCrashReporting cp_reportFatalCrashWithStackTrace:@{}]);
}

OCMVerify([self.mInstabug reportCrashWithStackTrace:@{} handled:isHandled]);

- (void)testSendNonFatalErrorJsonCrash {
NSString *jsonCrash = @"{}";
NSString *fingerPrint = @"fingerprint";
NSDictionary *userAttributes = @{@"key": @"value",};
NSString *ibgNonFatalLevel = @"NonFatalExceptionLevel.error";

FlutterError *error;

[self.api sendNonFatalErrorJsonCrash:jsonCrash
userAttributes:userAttributes
fingerprint:fingerPrint
nonFatalExceptionLevel:ibgNonFatalLevel
error:&error];

OCMVerify([self.mCrashReporting cp_reportNonFatalCrashWithStackTrace:@{}
level:IBGNonFatalLevelError
groupingString:fingerPrint
userAttributes:userAttributes
]);
}

@end
13 changes: 13 additions & 0 deletions example/ios/InstabugTests/Util/IBGCrashReporting+CP.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import <Instabug/Instabug.h>


@interface IBGCrashReporting (CP)

+ (void)cp_reportFatalCrashWithStackTrace:(NSDictionary*)stackTrace;

+ (void)cp_reportNonFatalCrashWithStackTrace:(NSDictionary*)stackTrace
level:(IBGNonFatalLevel)level
groupingString:(NSString *)groupingString
userAttributes:(NSDictionary<NSString *, NSString*> *)userAttributes;
@end

3 changes: 1 addition & 2 deletions example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '11.0'
platform :ios, '13.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand All @@ -26,7 +26,6 @@ end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
use_frameworks!
use_modular_headers!
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ SPEC CHECKSUMS:
instabug_flutter: 8b86ee14635a4b0ebfb4f760a108c7b0606c47e4
OCMock: 5ea90566be239f179ba766fd9fbae5885040b992

PODFILE CHECKSUM: 637e800c0a0982493b68adb612d2dd60c15c8e5c
PODFILE CHECKSUM: 85507f53c31d3e834227ea88986033537c7c78b9

COCOAPODS: 1.13.0
15 changes: 10 additions & 5 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -92,6 +92,7 @@
A964F0D42132F93F7E4DEB73 /* Pods-InstabugUITests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InstabugUITests.profile.xcconfig"; path = "Target Support Files/Pods-InstabugUITests/Pods-InstabugUITests.profile.xcconfig"; sourceTree = "<group>"; };
B03C8370EEFE061BDDDA1DA1 /* Pods-InstabugUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InstabugUITests.debug.xcconfig"; path = "Target Support Files/Pods-InstabugUITests/Pods-InstabugUITests.debug.xcconfig"; sourceTree = "<group>"; };
BA5633844585BB93FE7BCCE7 /* Pods-InstabugTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InstabugTests.profile.xcconfig"; path = "Target Support Files/Pods-InstabugTests/Pods-InstabugTests.profile.xcconfig"; sourceTree = "<group>"; };
BE26C80C2BD55575009FECCF /* IBGCrashReporting+CP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "IBGCrashReporting+CP.h"; sourceTree = "<group>"; };
BF9025BBD0A6FD7B193E903A /* Pods-InstabugTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InstabugTests.debug.xcconfig"; path = "Target Support Files/Pods-InstabugTests/Pods-InstabugTests.debug.xcconfig"; sourceTree = "<group>"; };
C090017925D9A030006F3DAE /* InstabugTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InstabugTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C090017D25D9A031006F3DAE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -261,6 +262,7 @@
CC78720A2938D1C5008CB2A5 /* Util */ = {
isa = PBXGroup;
children = (
BE26C80C2BD55575009FECCF /* IBGCrashReporting+CP.h */,
CC78720E293CA8EE008CB2A5 /* Instabug+Test.h */,
CC787211293CAB28008CB2A5 /* IBGNetworkLogger+Test.h */,
CC198C62293E2392007077C8 /* IBGSurvey+Test.h */,
Expand Down Expand Up @@ -350,7 +352,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down Expand Up @@ -453,10 +455,12 @@
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
Expand Down Expand Up @@ -484,6 +488,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand Down Expand Up @@ -681,7 +686,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down Expand Up @@ -767,7 +772,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -816,7 +821,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Loading