Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "prerelease",
"comment": "Fix ReactInstance error state to avoid crashes",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch",
"date": "2020-05-22T05:04:55.630Z"
}
7 changes: 6 additions & 1 deletion vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,12 @@ void ReactInstanceWin::OnReactInstanceLoaded(const Mso::ErrorCode &errorCode) no
if (auto strongThis = weakThis.GetStrongPtr()) {
if (!strongThis->m_isLoaded) {
strongThis->m_isLoaded = true;
strongThis->m_state = ReactInstanceState::Loaded;
if (!errorCode) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when I looked at this, I saw that if I let the instance stay in HasError, I could never reload the app:
the repro was:
don't start the bundler
start the app, get redbox, instance goes to HasError
press reload ----> no reload happens but redbox gets dismissed. app is left unusable.

Can you please confirm this works? can you think of why I might have seen that? 😋

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reload button works. If I dismiss the redbox, the app seems to unusable, but I can click Ctrl+Shift+D to reload it. If I run the "yarn start" before the reload, then I see the UI.

I guess the main difference between this change and what probably you did is that I let all other code to run as it was before. It is very important for the rest of the system to report that the load process is completed, even if it is completed in an error state. It allows to propagate all the messages and complete the load operation in the ActionQueue.

The ActionQueue expects that each action reports completion before it starts the next one. BTW, it also coalesce the actions. E.g. if unload is requested multiple times, only one of them is kept.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have verified the scenario again. The reloading worked fine as described above. I saw the app crash when we resize the window. It was caused by the RedBox code. I think we must clean the m_redboxContent on the RedBox closing.

@acoates-ms could you please see if changes to the RedBox look good?

strongThis->m_state = ReactInstanceState::Loaded;
} else {
strongThis->m_state = ReactInstanceState::HasError;
}

if (auto onLoaded = strongThis->m_options.OnInstanceLoaded.Get()) {
onLoaded->Invoke(*strongThis, errorCode);
}
Expand Down
11 changes: 7 additions & 4 deletions vnext/Microsoft.ReactNative/RedBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ struct RedBox : public std::enable_shared_from_this<RedBox> {
}

void WindowSizeChanged(winrt::Windows::UI::Core::WindowSizeChangedEventArgs const &args) noexcept {
m_redboxContent.MaxHeight(args.Size().Height);
m_redboxContent.Height(args.Size().Height);
m_redboxContent.MaxWidth(args.Size().Width);
m_redboxContent.Width(args.Size().Width);
if (m_redboxContent) {
m_redboxContent.MaxHeight(args.Size().Height);
m_redboxContent.Height(args.Size().Height);
m_redboxContent.MaxWidth(args.Size().Width);
m_redboxContent.Width(args.Size().Width);
}
}

void ShowNewJSError() noexcept {
Expand Down Expand Up @@ -138,6 +140,7 @@ struct RedBox : public std::enable_shared_from_this<RedBox> {
m_reloadButton.Click(m_tokenReload);
xaml::Window::Current().SizeChanged(m_tokenSizeChanged);
m_popup.Closed(m_tokenClosed);
m_redboxContent = nullptr;
m_onClosedCallback(GetId());
}

Expand Down