diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.java index 5b185d64b1..337e3abfcc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.java @@ -9,7 +9,8 @@ package com.facebook.react.modules.core; -import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.facebook.common.logging.FLog; import com.facebook.react.bridge.BaseJavaModule; @@ -22,6 +23,7 @@ import com.facebook.react.common.ReactConstants; public class ExceptionsManagerModule extends BaseJavaModule { + static private final Pattern mJsModuleIdPattern = Pattern.compile("(?:^|[/\\\\])(\\d+\\.js)$"); private final DevSupportManager mDevSupportManager; public ExceptionsManagerModule(DevSupportManager devSupportManager) { @@ -33,6 +35,23 @@ public class ExceptionsManagerModule extends BaseJavaModule { return "RKExceptionsManager"; } + // If the file name of a stack frame is numeric (+ ".js"), we assume it's a lazily injected module + // coming from a "random access bundle". We are using special source maps for these bundles, so + // that we can symbolicate stack traces for multiple injected files with a single source map. + // We have to include the module id in the stack for that, though. The ".js" suffix is kept to + // avoid ambiguities between "module-id:line" and "line:column". + static private String stackFrameToModuleId(ReadableMap frame) { + if (frame.hasKey("file") && + !frame.isNull("file") && + frame.getType("file") == ReadableType.String) { + final Matcher matcher = mJsModuleIdPattern.matcher(frame.getString("file")); + if (matcher.find()) { + return matcher.group(1) + ":"; + } + } + return ""; + } + private String stackTraceToString(String message, ReadableArray stack) { StringBuilder stringBuilder = new StringBuilder(message).append(", stack:\n"); for (int i = 0; i < stack.size(); i++) { @@ -40,6 +59,7 @@ public class ExceptionsManagerModule extends BaseJavaModule { stringBuilder .append(frame.getString("methodName")) .append("@") + .append(stackFrameToModuleId(frame)) .append(frame.getInt("lineNumber")); if (frame.hasKey("column") && !frame.isNull("column") &&