Skip to content

Instantly share code, notes, and snippets.

@surendharreddy
Last active November 18, 2019 03:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save surendharreddy/2b7eb417c7c08ac1cf7d496a0401c0ed to your computer and use it in GitHub Desktop.
Save surendharreddy/2b7eb417c7c08ac1cf7d496a0401c0ed to your computer and use it in GitHub Desktop.
JS Stack Trace with a fix too handle `NoSuchKeyException` when parsing JS stack frames without line numbers. (https://github.com/facebook/react-native/commit/c953e0b4319da0976ece877c09b648a55bc57d9f#diff-b1f4759dd5826c5a70a67e2790a1febf)
/**
* Copyright (c) Facebook, Inc. and its 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 java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
public class JSStackTrace {
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("methodName"))
.append("@")
.append(parseFileId(frame))
if (frame.hasKey("lineNumber") &&
!frame.isNull("lineNumber") &&
frame.getType("lineNumber") == ReadableType.Number) {
stringBuilder
.append(frame.getInt("lineNumber"));
} else {
stringBuilder
.append(-1);
}
if (frame.hasKey("column") &&
!frame.isNull("column") &&
frame.getType("column") == ReadableType.Number) {
stringBuilder
.append(":")
.append(frame.getInt("column"));
}
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") &&
!frame.isNull("file") &&
frame.getType("file") == ReadableType.String) {
final Matcher matcher = FILE_ID_PATTERN.matcher(frame.getString("file"));
if (matcher.find()) {
return matcher.group(1) + ":";
}
}
return "";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment