Skip to content

Commit 4792671

Browse files
alanleedevfacebook-github-bot
authored andcommitted
extract ParsedError handling to helper (facebook#44922)
Summary: Pull Request resolved: facebook#44922 extract ParsedError handling code into `StackTraceHelperTest`. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D58512611 fbshipit-source-id: 959978d80907f2afba96ef249c2fddd351d099ff
1 parent fe7e7a0 commit 4792671

File tree

4 files changed

+107
-25
lines changed

4 files changed

+107
-25
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2323,12 +2323,19 @@ public class com/facebook/react/devsupport/ReleaseDevSupportManager : com/facebo
23232323

23242324
public class com/facebook/react/devsupport/StackTraceHelper {
23252325
public static final field COLUMN_KEY Ljava/lang/String;
2326+
public static final field FILE_KEY Ljava/lang/String;
2327+
public static final field ID_KEY Ljava/lang/String;
2328+
public static final field IS_FATAL_KEY Ljava/lang/String;
23262329
public static final field LINE_NUMBER_KEY Ljava/lang/String;
2330+
public static final field MESSAGE_KEY Ljava/lang/String;
2331+
public static final field METHOD_NAME_KEY Ljava/lang/String;
2332+
public static final field STACK_KEY Ljava/lang/String;
23272333
public fun <init> ()V
23282334
public static fun convertJavaStackTrace (Ljava/lang/Throwable;)[Lcom/facebook/react/devsupport/interfaces/StackFrame;
23292335
public static fun convertJsStackTrace (Lcom/facebook/react/bridge/ReadableArray;)[Lcom/facebook/react/devsupport/interfaces/StackFrame;
23302336
public static fun convertJsStackTrace (Ljava/lang/String;)[Lcom/facebook/react/devsupport/interfaces/StackFrame;
23312337
public static fun convertJsStackTrace (Lorg/json/JSONArray;)[Lcom/facebook/react/devsupport/interfaces/StackFrame;
2338+
public static fun convertParsedError (Lcom/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler$ParsedError;)Lcom/facebook/react/bridge/JavaOnlyMap;
23322339
public static fun formatFrameSource (Lcom/facebook/react/devsupport/interfaces/StackFrame;)Ljava/lang/String;
23332340
public static fun formatStackTrace (Ljava/lang/String;[Lcom/facebook/react/devsupport/interfaces/StackFrame;)Ljava/lang/String;
23342341
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/StackTraceHelper.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@
88
package com.facebook.react.devsupport;
99

1010
import androidx.annotation.Nullable;
11+
import com.facebook.react.bridge.JavaOnlyArray;
12+
import com.facebook.react.bridge.JavaOnlyMap;
1113
import com.facebook.react.bridge.ReadableArray;
1214
import com.facebook.react.bridge.ReadableMap;
1315
import com.facebook.react.bridge.ReadableType;
1416
import com.facebook.react.common.MapBuilder;
1517
import com.facebook.react.devsupport.interfaces.StackFrame;
18+
import com.facebook.react.interfaces.exceptionmanager.ReactJsExceptionHandler.ParsedError;
1619
import java.io.File;
20+
import java.util.ArrayList;
21+
import java.util.List;
1722
import java.util.regex.Matcher;
1823
import java.util.regex.Pattern;
1924
import org.json.JSONArray;
@@ -23,8 +28,15 @@
2328
/** Helper class converting JS and Java stack traces into arrays of {@link StackFrame} objects. */
2429
public class StackTraceHelper {
2530

26-
public static final java.lang.String COLUMN_KEY = "column";
27-
public static final java.lang.String LINE_NUMBER_KEY = "lineNumber";
31+
public static final String COLUMN_KEY = "column";
32+
public static final String LINE_NUMBER_KEY = "lineNumber";
33+
public static final String FILE_KEY = "file";
34+
public static final String METHOD_NAME_KEY = "methodName";
35+
36+
public static final String MESSAGE_KEY = "message";
37+
public static final String STACK_KEY = "stack";
38+
public static final String ID_KEY = "id";
39+
public static final String IS_FATAL_KEY = "isFatal";
2840

2941
private static final Pattern STACK_FRAME_PATTERN1 =
3042
Pattern.compile("^(?:(.*?)@)?(.*?)\\:([0-9]+)\\:([0-9]+)$");
@@ -246,4 +258,25 @@ public static String formatStackTrace(String title, StackFrame[] stack) {
246258

247259
return stackTrace.toString();
248260
}
261+
262+
public static JavaOnlyMap convertParsedError(ParsedError error) {
263+
List<ParsedError.StackFrame> frames = error.getFrames();
264+
List<ReadableMap> readableMapList = new ArrayList<>();
265+
for (ParsedError.StackFrame frame : frames) {
266+
JavaOnlyMap map = new JavaOnlyMap();
267+
map.putDouble(COLUMN_KEY, frame.getColumnNumber());
268+
map.putDouble(LINE_NUMBER_KEY, frame.getLineNumber());
269+
map.putString(FILE_KEY, (String) frame.getFileName());
270+
map.putString(METHOD_NAME_KEY, (String) frame.getMethodName());
271+
readableMapList.add(map);
272+
}
273+
274+
JavaOnlyMap data = new JavaOnlyMap();
275+
data.putString(MESSAGE_KEY, error.getMessage());
276+
data.putArray(STACK_KEY, JavaOnlyArray.from(readableMapList));
277+
data.putInt(ID_KEY, error.getExceptionId());
278+
data.putBoolean(IS_FATAL_KEY, error.isFatal());
279+
280+
return data;
281+
}
249282
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77

88
package com.facebook.react.runtime;
99

10-
import static com.facebook.react.util.JSStackTrace.COLUMN_KEY;
11-
import static com.facebook.react.util.JSStackTrace.FILE_KEY;
12-
import static com.facebook.react.util.JSStackTrace.LINE_NUMBER_KEY;
13-
import static com.facebook.react.util.JSStackTrace.METHOD_NAME_KEY;
14-
1510
import android.content.res.AssetManager;
1611
import android.view.View;
1712
import com.facebook.common.logging.FLog;
@@ -28,15 +23,13 @@
2823
import com.facebook.react.bridge.Arguments;
2924
import com.facebook.react.bridge.JSBundleLoader;
3025
import com.facebook.react.bridge.JSBundleLoaderDelegate;
31-
import com.facebook.react.bridge.JavaOnlyArray;
3226
import com.facebook.react.bridge.JavaOnlyMap;
3327
import com.facebook.react.bridge.JavaScriptContextHolder;
3428
import com.facebook.react.bridge.NativeArray;
3529
import com.facebook.react.bridge.NativeMap;
3630
import com.facebook.react.bridge.NativeModule;
3731
import com.facebook.react.bridge.ReactNoCrashSoftException;
3832
import com.facebook.react.bridge.ReactSoftExceptionLogger;
39-
import com.facebook.react.bridge.ReadableMap;
4033
import com.facebook.react.bridge.RuntimeExecutor;
4134
import com.facebook.react.bridge.RuntimeScheduler;
4235
import com.facebook.react.bridge.queue.MessageQueueThread;
@@ -45,6 +38,7 @@
4538
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
4639
import com.facebook.react.bridge.queue.ReactQueueConfigurationImpl;
4740
import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec;
41+
import com.facebook.react.devsupport.StackTraceHelper;
4842
import com.facebook.react.devsupport.interfaces.DevSupportManager;
4943
import com.facebook.react.fabric.Binding;
5044
import com.facebook.react.fabric.BindingImpl;
@@ -332,22 +326,7 @@ private class ReactJsExceptionHandlerImpl implements ReactJsExceptionHandler {
332326

333327
@Override
334328
public void reportJsException(ParsedError error) {
335-
List<ReactJsExceptionHandler.ParsedError.StackFrame> frames = error.getFrames();
336-
List<ReadableMap> readableMapList = new ArrayList<>();
337-
for (ReactJsExceptionHandler.ParsedError.StackFrame frame : frames) {
338-
JavaOnlyMap map = new JavaOnlyMap();
339-
map.putDouble(COLUMN_KEY, frame.getColumnNumber());
340-
map.putDouble(LINE_NUMBER_KEY, frame.getLineNumber());
341-
map.putString(FILE_KEY, (String) frame.getFileName());
342-
map.putString(METHOD_NAME_KEY, (String) frame.getMethodName());
343-
readableMapList.add(map);
344-
}
345-
346-
JavaOnlyMap data = new JavaOnlyMap();
347-
data.putString("message", error.getMessage());
348-
data.putArray("stack", JavaOnlyArray.from(readableMapList));
349-
data.putInt("id", error.getExceptionId());
350-
data.putBoolean("isFatal", error.isFatal());
329+
JavaOnlyMap data = StackTraceHelper.convertParsedError(error);
351330

352331
// Simulate async native module method call
353332
mNativemodulesmessagequeuethread.runOnQueue(

packages/react-native/ReactAndroid/src/test/java/com/facebook/react/devsupport/StackTraceHelperTest.kt

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77

88
package com.facebook.react.devsupport
99

10+
import com.facebook.react.bridge.ReadableMap
11+
import com.facebook.react.common.annotations.UnstableReactNativeAPI
12+
import com.facebook.react.interfaces.exceptionmanager.ReactJsExceptionHandler.*
1013
import org.assertj.core.api.Assertions.assertThat
1114
import org.junit.Test
1215
import org.junit.runner.RunWith
1316
import org.robolectric.RobolectricTestRunner
1417

18+
@OptIn(UnstableReactNativeAPI::class)
1519
@RunWith(RobolectricTestRunner::class)
1620
class StackTraceHelperTest {
1721
@Test
@@ -58,4 +62,63 @@ class StackTraceHelperTest {
5862
assertThat(frame.line).isEqualTo(-1)
5963
assertThat(frame.column).isEqualTo(-1)
6064
}
65+
66+
@Test
67+
fun testConvertParsedError() {
68+
val error = getParsedErrorTestData()
69+
70+
val data = StackTraceHelper.convertParsedError(error)
71+
assertThat(data.getString("message")).isEqualTo("error message")
72+
assertThat(data.getInt("id")).isEqualTo(123)
73+
assertThat(data.getBoolean("isFatal")).isEqualTo(true)
74+
75+
val stack = data.getArray("stack")
76+
assertThat(stack).isNotNull()
77+
stack?.let {
78+
assertThat(stack.size()).isEqualTo(2)
79+
assertStackFrameMap(stack.getMap(0), "file1", "method1", 1, 10)
80+
assertStackFrameMap(stack.getMap(1), "file2", "method2", 2, 20)
81+
}
82+
}
83+
84+
private fun assertStackFrameMap(
85+
map: ReadableMap,
86+
filename: String,
87+
methodName: String,
88+
lineNumber: Int,
89+
columnNumber: Int
90+
) {
91+
92+
assertThat(map.getString("file")).isEqualTo(filename)
93+
assertThat(map.getString("methodName")).isEqualTo(methodName)
94+
assertThat(map.getDouble("lineNumber").toInt()).isEqualTo(lineNumber)
95+
assertThat(map.getDouble("column").toInt()).isEqualTo(columnNumber)
96+
}
97+
98+
private fun getParsedErrorTestData(): ParsedError {
99+
val frame1 =
100+
object : ParsedError.StackFrame {
101+
override val fileName = "file1"
102+
override val methodName = "method1"
103+
override val lineNumber = 1
104+
override val columnNumber = 10
105+
}
106+
107+
val frame2 =
108+
object : ParsedError.StackFrame {
109+
override val fileName = "file2"
110+
override val methodName = "method2"
111+
override val lineNumber = 2
112+
override val columnNumber = 20
113+
}
114+
115+
val frames = listOf(frame1, frame2)
116+
117+
return object : ParsedError {
118+
override val frames = frames
119+
override val message = "error message"
120+
override val exceptionId = 123
121+
override val isFatal = true
122+
}
123+
}
61124
}

0 commit comments

Comments
 (0)