Skip to content

Commit 468d1a2

Browse files
motiz88facebook-github-bot
authored andcommitted
Render collapsed frames in RedBox
Summary: Renders frames in RedBox in a greyed-out style when their `collapse` field is set to `true`. This avoids outright hiding information in the stack trace while still drawing attention to frames that are likely to be more meaningful. Changelog: [General] [Changed] - Render collapsed JavaScript frames in RedBox Reviewed By: rickhanlonii Differential Revision: D18039438 fbshipit-source-id: 527588f11c0bff495842be7036cd1293bab65eb9
1 parent 25e4265 commit 468d1a2

File tree

7 files changed

+40
-14
lines changed

7 files changed

+40
-14
lines changed

Libraries/Core/ExceptionsManager.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,9 @@ function reportException(e: ExtendedError, isFatal: boolean) {
106106
symbolicateStackTrace(stack)
107107
.then(prettyStack => {
108108
if (prettyStack) {
109-
const stackWithoutCollapsedFrames = prettyStack.filter(
110-
frame => !frame.collapse,
111-
);
112109
NativeExceptionsManager.updateExceptionMessage(
113110
data.message,
114-
stackWithoutCollapsedFrames,
111+
prettyStack,
115112
currentExceptionID,
116113
);
117114
} else {

React/Base/RCTJSStackFrame.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
@property (nonatomic, copy, readonly) NSString *file;
1414
@property (nonatomic, readonly) NSInteger lineNumber;
1515
@property (nonatomic, readonly) NSInteger column;
16+
@property (nonatomic, readonly) NSInteger collapse;
1617

17-
- (instancetype)initWithMethodName:(NSString *)methodName file:(NSString *)file lineNumber:(NSInteger)lineNumber column:(NSInteger)column;
18+
- (instancetype)initWithMethodName:(NSString *)methodName file:(NSString *)file lineNumber:(NSInteger)lineNumber column:(NSInteger)column collapse:(NSInteger)collapse;
1819
- (NSDictionary *)toDictionary;
1920

2021
+ (instancetype)stackFrameWithLine:(NSString *)line;

React/Base/RCTJSStackFrame.m

+8-4
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@
5353

5454
@implementation RCTJSStackFrame
5555

56-
- (instancetype)initWithMethodName:(NSString *)methodName file:(NSString *)file lineNumber:(NSInteger)lineNumber column:(NSInteger)column
56+
- (instancetype)initWithMethodName:(NSString *)methodName file:(NSString *)file lineNumber:(NSInteger)lineNumber column:(NSInteger)column collapse:(NSInteger)collapse
5757
{
5858
if (self = [super init]) {
5959
_methodName = methodName;
6060
_file = file;
6161
_lineNumber = lineNumber;
6262
_column = column;
63+
_collapse = collapse;
6364
}
6465
return self;
6566
}
@@ -70,7 +71,8 @@ - (NSDictionary *)toDictionary
7071
@"methodName": RCTNullIfNil(self.methodName),
7172
@"file": RCTNullIfNil(self.file),
7273
@"lineNumber": @(self.lineNumber),
73-
@"column": @(self.column)
74+
@"column": @(self.column),
75+
@"collapse": @(self.collapse)
7476
};
7577
}
7678

@@ -91,15 +93,17 @@ + (instancetype)stackFrameWithLine:(NSString *)line
9193
return [[self alloc] initWithMethodName:methodName
9294
file:file
9395
lineNumber:[lineNumber integerValue]
94-
column:[column integerValue]];
96+
column:[column integerValue]
97+
collapse:@NO];
9598
}
9699

97100
+ (instancetype)stackFrameWithDictionary:(NSDictionary *)dict
98101
{
99102
return [[self alloc] initWithMethodName:RCTNilIfNull(dict[@"methodName"])
100103
file:dict[@"file"]
101104
lineNumber:[RCTNilIfNull(dict[@"lineNumber"]) integerValue]
102-
column:[RCTNilIfNull(dict[@"column"]) integerValue]];
105+
column:[RCTNilIfNull(dict[@"column"]) integerValue]
106+
collapse:[RCTNilIfNull(dict[@"collapse"]) integerValue]];
103107
}
104108

105109
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithLines:(NSString *)lines

React/Modules/RCTRedBox.m

+4-1
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,6 @@ - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forStackFrame:(RCTJSStack
353353
{
354354
if (!cell) {
355355
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
356-
cell.textLabel.textColor = [UIColor whiteColor];
357356
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14];
358357
cell.textLabel.lineBreakMode = NSLineBreakByCharWrapping;
359358
cell.textLabel.numberOfLines = 2;
@@ -371,6 +370,10 @@ - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forStackFrame:(RCTJSStack
371370
} else {
372371
cell.detailTextLabel.text = @"";
373372
}
373+
cell.textLabel.textColor = stackFrame.collapse ? [UIColor lightGrayColor] : [UIColor whiteColor];
374+
cell.detailTextLabel.textColor = stackFrame.collapse ?
375+
[UIColor colorWithRed:0.50 green:0.50 blue:0.50 alpha:1.0] :
376+
[UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
374377
return cell;
375378
}
376379

ReactAndroid/src/main/java/com/facebook/react/devsupport/RedBoxDialog.java

+2
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ public View getView(int position, View convertView, ViewGroup parent) {
186186
FrameViewHolder holder = (FrameViewHolder) convertView.getTag();
187187
holder.mMethodView.setText(frame.getMethod());
188188
holder.mFileView.setText(StackTraceHelper.formatFrameSource(frame));
189+
holder.mMethodView.setTextColor(frame.isCollapsed() ? 0xFFAAAAAA : Color.WHITE);
190+
holder.mFileView.setTextColor(frame.isCollapsed() ? 0xFF808080 : 0xFFB3B3B3);
189191
return convertView;
190192
}
191193
}

ReactAndroid/src/main/java/com/facebook/react/devsupport/StackTraceHelper.java

+20-4
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,19 @@ public static class StackFrameImpl implements StackFrame {
3838
private final int mLine;
3939
private final int mColumn;
4040
private final String mFileName;
41+
private final boolean mIsCollapsed;
4142

42-
private StackFrameImpl(String file, String method, int line, int column) {
43+
private StackFrameImpl(String file, String method, int line, int column, boolean isCollapsed) {
4344
mFile = file;
4445
mMethod = method;
4546
mLine = line;
4647
mColumn = column;
4748
mFileName = file != null ? new File(file).getName() : "";
49+
mIsCollapsed = isCollapsed;
50+
}
51+
52+
private StackFrameImpl(String file, String method, int line, int column) {
53+
this(file, method, line, column, false);
4854
}
4955

5056
private StackFrameImpl(String file, String fileName, String method, int line, int column) {
@@ -53,6 +59,7 @@ private StackFrameImpl(String file, String fileName, String method, int line, in
5359
mMethod = method;
5460
mLine = line;
5561
mColumn = column;
62+
mIsCollapsed = false;
5663
}
5764

5865
/**
@@ -90,14 +97,19 @@ public String getFileName() {
9097
return mFileName;
9198
}
9299

100+
public boolean isCollapsed() {
101+
return mIsCollapsed;
102+
}
103+
93104
/** Convert the stack frame to a JSON representation. */
94105
public JSONObject toJSON() {
95106
return new JSONObject(
96107
MapBuilder.of(
97108
"file", getFile(),
98109
"methodName", getMethod(),
99110
"lineNumber", getLine(),
100-
"column", getColumn()));
111+
"column", getColumn(),
112+
"collapse", isCollapsed()));
101113
}
102114
}
103115

@@ -114,6 +126,8 @@ public static StackFrame[] convertJsStackTrace(@Nullable ReadableArray stack) {
114126
ReadableMap frame = stack.getMap(i);
115127
String methodName = frame.getString("methodName");
116128
String fileName = frame.getString("file");
129+
boolean collapse =
130+
frame.hasKey("collapse") && !frame.isNull("collapse") && frame.getBoolean("collapse");
117131
int lineNumber = -1;
118132
if (frame.hasKey(LINE_NUMBER_KEY) && !frame.isNull(LINE_NUMBER_KEY)) {
119133
lineNumber = frame.getInt(LINE_NUMBER_KEY);
@@ -122,7 +136,7 @@ public static StackFrame[] convertJsStackTrace(@Nullable ReadableArray stack) {
122136
if (frame.hasKey(COLUMN_KEY) && !frame.isNull(COLUMN_KEY)) {
123137
columnNumber = frame.getInt(COLUMN_KEY);
124138
}
125-
result[i] = new StackFrameImpl(fileName, methodName, lineNumber, columnNumber);
139+
result[i] = new StackFrameImpl(fileName, methodName, lineNumber, columnNumber, collapse);
126140
} else if (type == ReadableType.String) {
127141
result[i] = new StackFrameImpl(null, stack.getString(i), -1, -1);
128142
}
@@ -150,7 +164,9 @@ public static StackFrame[] convertJsStackTrace(JSONArray stack) {
150164
if (frame.has(COLUMN_KEY) && !frame.isNull(COLUMN_KEY)) {
151165
columnNumber = frame.getInt(COLUMN_KEY);
152166
}
153-
result[i] = new StackFrameImpl(fileName, methodName, lineNumber, columnNumber);
167+
boolean collapse =
168+
frame.has("collapse") && !frame.isNull("collapse") && frame.getBoolean("collapse");
169+
result[i] = new StackFrameImpl(fileName, methodName, lineNumber, columnNumber, collapse);
154170
}
155171
} catch (JSONException exception) {
156172
throw new RuntimeException(exception);

ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/StackFrame.java

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public interface StackFrame {
3636
*/
3737
public String getFileName();
3838

39+
/** Whether this frame is collapsed. */
40+
public boolean isCollapsed();
41+
3942
/** Convert the stack frame to a JSON representation. */
4043
public JSONObject toJSON();
4144
}

0 commit comments

Comments
 (0)