Move stack trace formatting in own class
Summary: Moves stack trace formatting logic into its own class to facilitate reusage from custom exception managers. Reviewed By: javache Differential Revision: D5086336 fbshipit-source-id: f434a1621c599c5c49991b3bfe5f66d05f84b5c9
This commit is contained in:
parent
056d075ef2
commit
d7659a0ec6
|
@ -15,5 +15,6 @@ android_library(
|
||||||
react_native_target("java/com/facebook/react/devsupport:interfaces"),
|
react_native_target("java/com/facebook/react/devsupport:interfaces"),
|
||||||
react_native_target("java/com/facebook/react/jstasks:jstasks"),
|
react_native_target("java/com/facebook/react/jstasks:jstasks"),
|
||||||
react_native_target("java/com/facebook/react/module/annotations:annotations"),
|
react_native_target("java/com/facebook/react/module/annotations:annotations"),
|
||||||
|
react_native_target("java/com/facebook/react/util:util"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,26 +9,21 @@
|
||||||
|
|
||||||
package com.facebook.react.modules.core;
|
package com.facebook.react.modules.core;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import com.facebook.common.logging.FLog;
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.react.bridge.BaseJavaModule;
|
import com.facebook.react.bridge.BaseJavaModule;
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
|
||||||
import com.facebook.react.bridge.ReadableType;
|
|
||||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
|
||||||
import com.facebook.react.common.JavascriptException;
|
import com.facebook.react.common.JavascriptException;
|
||||||
import com.facebook.react.common.ReactConstants;
|
import com.facebook.react.common.ReactConstants;
|
||||||
|
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||||
import com.facebook.react.module.annotations.ReactModule;
|
import com.facebook.react.module.annotations.ReactModule;
|
||||||
|
import com.facebook.react.util.JSStackTrace;
|
||||||
|
|
||||||
@ReactModule(name = ExceptionsManagerModule.NAME)
|
@ReactModule(name = ExceptionsManagerModule.NAME)
|
||||||
public class ExceptionsManagerModule extends BaseJavaModule {
|
public class ExceptionsManagerModule extends BaseJavaModule {
|
||||||
|
|
||||||
protected static final String NAME = "ExceptionsManager";
|
protected static final String NAME = "ExceptionsManager";
|
||||||
|
|
||||||
static private final Pattern mJsModuleIdPattern = Pattern.compile("(?:^|[/\\\\])(\\d+\\.js)$");
|
|
||||||
private final DevSupportManager mDevSupportManager;
|
private final DevSupportManager mDevSupportManager;
|
||||||
|
|
||||||
public ExceptionsManagerModule(DevSupportManager devSupportManager) {
|
public ExceptionsManagerModule(DevSupportManager devSupportManager) {
|
||||||
|
@ -40,44 +35,6 @@ public class ExceptionsManagerModule extends BaseJavaModule {
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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++) {
|
|
||||||
ReadableMap frame = stack.getMap(i);
|
|
||||||
stringBuilder
|
|
||||||
.append(frame.getString("methodName"))
|
|
||||||
.append("@")
|
|
||||||
.append(stackFrameToModuleId(frame))
|
|
||||||
.append(frame.getInt("lineNumber"));
|
|
||||||
if (frame.hasKey("column") &&
|
|
||||||
!frame.isNull("column") &&
|
|
||||||
frame.getType("column") == ReadableType.Number) {
|
|
||||||
stringBuilder
|
|
||||||
.append(":")
|
|
||||||
.append(frame.getInt("column"));
|
|
||||||
}
|
|
||||||
stringBuilder.append("\n");
|
|
||||||
}
|
|
||||||
return stringBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void reportFatalException(String title, ReadableArray details, int exceptionId) {
|
public void reportFatalException(String title, ReadableArray details, int exceptionId) {
|
||||||
showOrThrowError(title, details, exceptionId);
|
showOrThrowError(title, details, exceptionId);
|
||||||
|
@ -88,7 +45,7 @@ public class ExceptionsManagerModule extends BaseJavaModule {
|
||||||
if (mDevSupportManager.getDevSupportEnabled()) {
|
if (mDevSupportManager.getDevSupportEnabled()) {
|
||||||
mDevSupportManager.showNewJSError(title, details, exceptionId);
|
mDevSupportManager.showNewJSError(title, details, exceptionId);
|
||||||
} else {
|
} else {
|
||||||
FLog.e(ReactConstants.TAG, stackTraceToString(title, details));
|
FLog.e(ReactConstants.TAG, JSStackTrace.format(title, details));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +53,7 @@ public class ExceptionsManagerModule extends BaseJavaModule {
|
||||||
if (mDevSupportManager.getDevSupportEnabled()) {
|
if (mDevSupportManager.getDevSupportEnabled()) {
|
||||||
mDevSupportManager.showNewJSError(title, details, exceptionId);
|
mDevSupportManager.showNewJSError(title, details, exceptionId);
|
||||||
} else {
|
} else {
|
||||||
throw new JavascriptException(stackTraceToString(title, details));
|
throw new JavascriptException(JSStackTrace.format(title, details));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
include_defs("//ReactAndroid/DEFS")
|
||||||
|
|
||||||
|
android_library(
|
||||||
|
name = "util",
|
||||||
|
srcs = glob(["**/*.java"]),
|
||||||
|
visibility = [
|
||||||
|
"PUBLIC",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
react_native_target("java/com/facebook/react/bridge:bridge"),
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2017-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
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 {
|
||||||
|
|
||||||
|
final private static Pattern mJsModuleIdPattern = Pattern.compile("(?:^|[/\\\\])(\\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(stackFrameToModuleId(frame))
|
||||||
|
.append(frame.getInt("lineNumber"));
|
||||||
|
if (frame.hasKey("column") &&
|
||||||
|
!frame.isNull("column") &&
|
||||||
|
frame.getType("column") == ReadableType.Number) {
|
||||||
|
stringBuilder
|
||||||
|
.append(":")
|
||||||
|
.append(frame.getInt("column"));
|
||||||
|
}
|
||||||
|
stringBuilder.append("\n");
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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".
|
||||||
|
private static 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 "";
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue