mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
ab45138394
Summary: Why Lacrima? - Throw a JavascriptException in native won't get the js error reported to backend, we need to use reporter APIs - Lacrima is a new error reporting framework to report crashes and app deaths in android applications at Facebook, and it has APIs for reporting js exceptions. - ```FbErrorReporterImpl.java``` uses ```Acra``` API to report, and ```Lacrima``` is a rewrite of ```Acra``` https://fb.workplace.com/groups/323014308578038/ - We've been receiving js errors reported via Lacrima https://fburl.com/logview/y1vhc8u8 In this diff all js errors are treated as soft errors during reporting because they don't usually crash the app, crashes will be reported with a different category. Changelog: [Android][Chagned] - Change static string to public Reviewed By: fkgozali Differential Revision: D34095100 fbshipit-source-id: 73d89647134a197baf5d228d620732781b6bd723
73 lines
2.7 KiB
Java
73 lines
2.7 KiB
Java
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
package com.facebook.react.util;
|
|
|
|
import com.facebook.react.bridge.ReadableArray;
|
|
import com.facebook.react.bridge.ReadableMap;
|
|
import com.facebook.react.bridge.ReadableType;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
public class JSStackTrace {
|
|
|
|
public static final String LINE_NUMBER_KEY = "lineNumber";
|
|
public static final String FILE_KEY = "file";
|
|
public static final String COLUMN_KEY = "column";
|
|
public static final String METHOD_NAME_KEY = "methodName";
|
|
|
|
private static final Pattern FILE_ID_PATTERN =
|
|
Pattern.compile("\\b((?:seg-\\d+(?:_\\d+)?|\\d+)\\.js)");
|
|
|
|
public static String format(String message, ReadableArray stack) {
|
|
StringBuilder stringBuilder = new StringBuilder(message).append(", stack:\n");
|
|
for (int i = 0; i < stack.size(); i++) {
|
|
ReadableMap frame = stack.getMap(i);
|
|
stringBuilder.append(frame.getString(METHOD_NAME_KEY)).append("@").append(parseFileId(frame));
|
|
|
|
if (frame.hasKey(LINE_NUMBER_KEY)
|
|
&& !frame.isNull(LINE_NUMBER_KEY)
|
|
&& frame.getType(LINE_NUMBER_KEY) == ReadableType.Number) {
|
|
stringBuilder.append(frame.getInt(LINE_NUMBER_KEY));
|
|
} else {
|
|
stringBuilder.append(-1);
|
|
}
|
|
|
|
if (frame.hasKey(COLUMN_KEY)
|
|
&& !frame.isNull(COLUMN_KEY)
|
|
&& frame.getType(COLUMN_KEY) == ReadableType.Number) {
|
|
stringBuilder.append(":").append(frame.getInt(COLUMN_KEY));
|
|
}
|
|
|
|
stringBuilder.append("\n");
|
|
}
|
|
return stringBuilder.toString();
|
|
}
|
|
|
|
// Besides a regular bundle (e.g. "bundle.js"), a stack frame can be produced by:
|
|
// 1) "random access bundle (RAM)", e.g. "1.js", where "1" is a module name
|
|
// 2) "segment file", e.g. "seg-1.js", where "1" is a segment name
|
|
// 3) "RAM segment file", e.g. "seg-1_2.js", where "1" is a segment name and "2" is a module name
|
|
// We are using a special source map format for such cases, so that we could symbolicate
|
|
// stack traces with a single source map file.
|
|
// NOTE: The ".js" suffix is kept to avoid ambiguities between "module-id:line" and "line:column".
|
|
private static String parseFileId(ReadableMap frame) {
|
|
if (frame.hasKey(FILE_KEY)
|
|
&& !frame.isNull(FILE_KEY)
|
|
&& frame.getType(FILE_KEY) == ReadableType.String) {
|
|
String file = frame.getString(FILE_KEY);
|
|
if (file != null) {
|
|
final Matcher matcher = FILE_ID_PATTERN.matcher(file);
|
|
if (matcher.find()) {
|
|
return matcher.group(1) + ":";
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
}
|