Skip to content

Commit

Permalink
Fix crash inside RCTRedBox when trying to present same UIViewControll…
Browse files Browse the repository at this point in the history
…er twice

Summary:
Calling `-[RCTRedBox showErrorMessage]` twice causes a crash

We used `-[UIViewController isBeingPresented]` to tell whether view controller is already presented.
But from the documentation:

> A Boolean value indicating whether the view controller is being presented.

Source: https://developer.apple.com/documentation/uikit/uiviewcontroller/2097564-beingpresented?language=objc#

 ---
So this means that if you present it, wait until presentation animation is finished and then call `-[RCTRedBox showErrorMessage]` again, following exception will be thrown.

```
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <UIViewController: 0x7fc33e422f50>.'
```

Changelog: Fix crash caused by presenting view controller twice from RCTRedBox

Reviewed By: PeteTheHeat

Differential Revision: D20946645

fbshipit-source-id: 763066e37db4e56efb0118b2e7867ad0724bae81
  • Loading branch information
sammy-SC authored and facebook-github-bot committed Apr 10, 2020
1 parent 8988a07 commit 46c77dc
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions React/CoreModules/RCTRedBox.mm
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,11 @@ - (void)showErrorMessage:(NSString *)message
// Remove ANSI color codes from the message
NSString *messageWithoutAnsi = [self stripAnsi:message];

BOOL isRootViewControllerPresented = self.rootViewController.presentingViewController != nil;
// Show if this is a new message, or if we're updating the previous message
BOOL isNew = !self.rootViewController.isBeingPresented && !isUpdate;
BOOL isNew = !isRootViewControllerPresented && !isUpdate;
BOOL isUpdateForSameMessage = !isNew &&
(self.rootViewController.isBeingPresented && isUpdate &&
(isRootViewControllerPresented && isUpdate &&
((errorCookie == -1 && [_lastErrorMessage isEqualToString:messageWithoutAnsi]) ||
(errorCookie == _lastErrorCookie)));
if (isNew || isUpdateForSameMessage) {
Expand All @@ -250,7 +251,7 @@ - (void)showErrorMessage:(NSString *)message

[_stackTraceTableView reloadData];

if (!self.rootViewController.isBeingPresented) {
if (!isRootViewControllerPresented) {
[_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:NO];
Expand Down

0 comments on commit 46c77dc

Please sign in to comment.