Skip to content

Commit 5bd48e2

Browse files
a7medevahmedAlaaInstabug
authored andcommitted
fix(android): resolve an OOM in network logs (#1244)
1 parent 8b03f9c commit 5bd48e2

File tree

18 files changed

+621
-217
lines changed

18 files changed

+621
-217
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [Unreleased](https://github.com/Instabug/Instabug-React-Native/compare/v13.2.0...dev)
4+
5+
### Fixed
6+
7+
- Fix an OOM (out-of-memory) crash while saving network logs on Android ([#1244](https://github.com/Instabug/Instabug-React-Native/pull/1244)).
8+
39
## [13.2.0](https://github.com/Instabug/Instabug-React-Native/compare/v13.1.1...v13.2.0) (July 7, 2024)
410

511
### Changed

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

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import android.util.Log;
66

77
import androidx.annotation.NonNull;
8+
import androidx.annotation.Nullable;
9+
810
import com.facebook.react.bridge.Promise;
911
import com.facebook.react.bridge.ReactApplicationContext;
1012
import com.facebook.react.bridge.ReactContextBaseJavaModule;
@@ -312,56 +314,58 @@ public void run() {
312314
});
313315
}
314316

315-
/**
316-
* Send Apm network log by Reflection
317-
*/
318317
@ReactMethod
319-
public void networkLog(String networkData) throws JSONException {
320-
try{
321-
APMNetworkLogger apmNetworkLogger = new APMNetworkLogger();
322-
JSONObject jsonObject = new JSONObject(networkData);
323-
final String requestUrl = (String) jsonObject.get("url");
324-
final String requestBody = (String) jsonObject.get("requestBody");
325-
final String responseBody = (String) jsonObject.get("responseBody");
326-
final String requestMethod = (String) jsonObject.get("method");
327-
//--------------------------------------------
328-
final String requestContentType = (String) jsonObject.get("requestContentType");
329-
final String responseContentType = (String) jsonObject.get("contentType");
330-
//--------------------------------------------
331-
final long requestBodySize = ((Number) jsonObject.get("requestBodySize")).longValue();
332-
final long responseBodySize = ((Number) jsonObject.get("responseBodySize")).longValue();
333-
//--------------------------------------------
334-
final String errorDomain = (String) jsonObject.get("errorDomain");
335-
final Integer statusCode = (Integer) jsonObject.get("responseCode");
336-
final long requestDuration = ((Number) jsonObject.get("duration")).longValue();
337-
final long requestStartTime = ((Number) jsonObject.get("startTime")).longValue() * 1000;
338-
final String requestHeaders = (String) jsonObject.get("requestHeaders").toString();
339-
final String responseHeaders = (String) jsonObject.get("responseHeaders").toString();
340-
final String errorMessage;
341-
if(errorDomain.equals("")) {
342-
errorMessage = null;
343-
} else {
344-
errorMessage = errorDomain;
345-
}
346-
//--------------------------------------------
347-
String gqlQueryName = null;
348-
if(jsonObject.has("gqlQueryName")){
349-
gqlQueryName = (String) jsonObject.get("gqlQueryName");
350-
}
351-
final String serverErrorMessage = (String) jsonObject.get("serverErrorMessage");
318+
private void networkLogAndroid(final double requestStartTime,
319+
final double requestDuration,
320+
final String requestHeaders,
321+
final String requestBody,
322+
final double requestBodySize,
323+
final String requestMethod,
324+
final String requestUrl,
325+
final String requestContentType,
326+
final String responseHeaders,
327+
final String responseBody,
328+
final double responseBodySize,
329+
final double statusCode,
330+
final String responseContentType,
331+
@Nullable final String errorDomain,
332+
@Nullable final String gqlQueryName,
333+
@Nullable final String serverErrorMessage) {
334+
try {
335+
APMNetworkLogger networkLogger = new APMNetworkLogger();
336+
337+
final boolean hasError = errorDomain != null && !errorDomain.isEmpty();
338+
final String errorMessage = hasError ? errorDomain : null;
352339

353340
try {
354341
Method method = getMethod(Class.forName("com.instabug.apm.networking.APMNetworkLogger"), "log", long.class, long.class, String.class, String.class, long.class, String.class, String.class, String.class, String.class, String.class, long.class, int.class, String.class, String.class, String.class, String.class);
355342
if (method != null) {
356-
method.invoke(apmNetworkLogger, requestStartTime, requestDuration, requestHeaders, requestBody, requestBodySize, requestMethod, requestUrl, requestContentType, responseHeaders, responseBody, responseBodySize, statusCode, responseContentType, errorMessage, gqlQueryName, serverErrorMessage);
343+
method.invoke(
344+
networkLogger,
345+
requestStartTime,
346+
requestDuration,
347+
requestHeaders,
348+
requestBody,
349+
requestBodySize,
350+
requestMethod,
351+
requestUrl,
352+
requestContentType,
353+
responseHeaders,
354+
responseBody,
355+
responseBodySize,
356+
statusCode,
357+
responseContentType,
358+
errorMessage,
359+
gqlQueryName,
360+
serverErrorMessage
361+
);
357362
} else {
358-
Log.e("IB-CP-Bridge", "apmNetworkLogByReflection was not found by reflection");
363+
Log.e("IB-CP-Bridge", "APMNetworkLogger.log was not found by reflection");
359364
}
360365
} catch (Throwable e) {
361366
e.printStackTrace();
362367
}
363-
}
364-
catch(Throwable e) {
368+
} catch(Throwable e) {
365369
e.printStackTrace();
366370
}
367371
}

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

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.app.Application;
66
import android.graphics.Bitmap;
77
import android.net.Uri;
8+
import android.util.Log;
89
import android.view.View;
910

1011
import androidx.annotation.UiThread;
@@ -34,6 +35,7 @@
3435
import com.instabug.library.model.NetworkLog;
3536
import com.instabug.library.model.Report;
3637
import com.instabug.library.ui.onboarding.WelcomeMessage;
38+
import com.instabug.library.util.InstabugSDKLogger;
3739
import com.instabug.reactlibrary.utils.ArrayUtil;
3840
import com.instabug.reactlibrary.utils.EventEmitterModule;
3941
import com.instabug.reactlibrary.utils.MainThreadHandler;
@@ -60,7 +62,7 @@
6062
*/
6163
public class RNInstabugReactnativeModule extends EventEmitterModule {
6264

63-
private static final String TAG = RNInstabugReactnativeModule.class.getSimpleName();
65+
private static final String TAG = "IBG-RN-Core";
6466

6567
private InstabugCustomTextPlaceHolder placeHolders;
6668
private static Report currentReport;
@@ -895,27 +897,38 @@ public void run() {
895897
});
896898
}
897899

898-
/**
899-
* Extracts HTTP connection properties. Request method, Headers, Date, Url and Response code
900-
*
901-
* @param jsonObject the JSON object containing all HTTP connection properties
902-
* @throws JSONException
903-
*/
904900
@ReactMethod
905-
public void networkLog(String jsonObject) throws JSONException {
906-
NetworkLog networkLog = new NetworkLog();
907-
String date = System.currentTimeMillis()+"";
908-
networkLog.setDate(date);
909-
JSONObject newJSONObject = new JSONObject(jsonObject);
910-
networkLog.setUrl(newJSONObject.getString("url"));
911-
networkLog.setRequest(newJSONObject.getString("requestBody"));
912-
networkLog.setResponse(newJSONObject.getString("responseBody"));
913-
networkLog.setMethod(newJSONObject.getString("method"));
914-
networkLog.setResponseCode(newJSONObject.getInt("responseCode"));
915-
networkLog.setRequestHeaders(newJSONObject.getString("requestHeaders"));
916-
networkLog.setResponseHeaders(newJSONObject.getString("responseHeaders"));
917-
networkLog.setTotalDuration(newJSONObject.getLong("duration"));
918-
networkLog.insert();
901+
public void networkLogAndroid(final String url,
902+
final String requestBody,
903+
final String responseBody,
904+
final String method,
905+
final double responseCode,
906+
final String requestHeaders,
907+
final String responseHeaders,
908+
final double duration) {
909+
try {
910+
final String date = String.valueOf(System.currentTimeMillis());
911+
912+
NetworkLog networkLog = new NetworkLog();
913+
networkLog.setDate(date);
914+
networkLog.setUrl(url);
915+
networkLog.setMethod(method);
916+
networkLog.setResponseCode((int) responseCode);
917+
networkLog.setTotalDuration((long) duration);
918+
919+
try {
920+
networkLog.setRequest(requestBody);
921+
networkLog.setResponse(responseBody);
922+
networkLog.setRequestHeaders(requestHeaders);
923+
networkLog.setResponseHeaders(responseHeaders);
924+
} catch (OutOfMemoryError | Exception exception) {
925+
Log.d(TAG, "Error: " + exception.getMessage() + "while trying to set network log contents (request body, response body, request headers, and response headers).");
926+
}
927+
928+
networkLog.insert();
929+
} catch (OutOfMemoryError | Exception exception) {
930+
Log.d(TAG, "Error: " + exception.getMessage() + "while trying to insert a network log");
931+
}
919932
}
920933

921934
@UiThread

examples/default/ios/InstabugTests/InstabugSampleTests.m

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#import <Instabug/IBGTypes.h>
1414
#import "IBGConstants.h"
1515
#import "RNInstabug.h"
16+
#import <RNInstabug/IBGNetworkLogger+CP.h>
1617

1718
@protocol InstabugCPTestProtocol <NSObject>
1819
/**
@@ -313,6 +314,61 @@ - (void)testSetWelcomeMessageMode {
313314
OCMVerify([mock setWelcomeMessageMode:welcomeMessageMode]);
314315
}
315316

317+
- (void)testNetworkLogIOS {
318+
id mIBGNetworkLogger = OCMClassMock([IBGNetworkLogger class]);
319+
320+
NSString *url = @"https://api.instabug.com";
321+
NSString *method = @"GET";
322+
NSString *requestBody = @"requestBody";
323+
double requestBodySize = 10;
324+
NSString *responseBody = @"responseBody";
325+
double responseBodySize = 15;
326+
double responseCode = 200;
327+
NSDictionary *requestHeaders = @{ @"accept": @"application/json" };
328+
NSDictionary *responseHeaders = @{ @"cache-control": @"no-store" };
329+
NSString *contentType = @"application/json";
330+
double errorCode = 0;
331+
NSString *errorDomain = nil;
332+
double startTime = 1719847101199;
333+
double duration = 150;
334+
NSString *gqlQueryName = nil;
335+
NSString *serverErrorMessage = nil;
336+
337+
[self.instabugBridge networkLogIOS:url
338+
method:method
339+
requestBody:requestBody
340+
requestBodySize:requestBodySize
341+
responseBody:responseBody
342+
responseBodySize:responseBodySize
343+
responseCode:responseCode
344+
requestHeaders:requestHeaders
345+
responseHeaders:responseHeaders
346+
contentType:contentType
347+
errorDomain:errorDomain
348+
errorCode:errorCode
349+
startTime:startTime
350+
duration:duration
351+
gqlQueryName:gqlQueryName
352+
serverErrorMessage:serverErrorMessage];
353+
354+
OCMVerify([mIBGNetworkLogger addNetworkLogWithUrl:url
355+
method:method
356+
requestBody:requestBody
357+
requestBodySize:requestBodySize
358+
responseBody:responseBody
359+
responseBodySize:responseBodySize
360+
responseCode:responseCode
361+
requestHeaders:requestHeaders
362+
responseHeaders:responseHeaders
363+
contentType:contentType
364+
errorDomain:errorDomain
365+
errorCode:errorCode
366+
startTime:startTime * 1000
367+
duration:duration * 1000
368+
gqlQueryName:gqlQueryName
369+
serverErrorMessage:serverErrorMessage]);
370+
}
371+
316372
- (void)testSetFileAttachment {
317373
id mock = OCMClassMock([Instabug class]);
318374
NSString *fileLocation = @"test";

ios/RNInstabug/InstabugReactBridge.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@
107107

108108
- (void)setNetworkLoggingEnabled:(BOOL)isEnabled;
109109

110+
- (void)networkLogIOS:(NSString * _Nonnull)url
111+
method:(NSString * _Nonnull)method
112+
requestBody:(NSString * _Nonnull)requestBody
113+
requestBodySize:(double)requestBodySize
114+
responseBody:(NSString * _Nonnull)responseBody
115+
responseBodySize:(double)responseBodySize
116+
responseCode:(double)responseCode
117+
requestHeaders:(NSDictionary * _Nonnull)requestHeaders
118+
responseHeaders:(NSDictionary * _Nonnull)responseHeaders
119+
contentType:(NSString * _Nonnull)contentType
120+
errorDomain:(NSString * _Nullable)errorDomain
121+
errorCode:(double)errorCode
122+
startTime:(double)startTime
123+
duration:(double)duration
124+
gqlQueryName:(NSString * _Nullable)gqlQueryName
125+
serverErrorMessage:(NSString * _Nullable)serverErrorMessage;
126+
110127
/*
111128
+------------------------------------------------------------------------+
112129
| Experiments |

0 commit comments

Comments
 (0)