diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index 578aa0e5d22f..b14d348de78b 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -4004,6 +4004,14 @@ void WebContents::ExitPictureInPicture() { PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture(); } +bool WebContents::ShouldFocusPageAfterCrash(content::WebContents* source) { + // WebView uses WebContentsViewChildFrame, which doesn't have a Focus impl + // and triggers a fatal NOTREACHED. + if (is_guest()) + return false; + return true; +} + void WebContents::DevToolsSaveToFile(const std::string& url, const std::string& content, bool save_as, diff --git a/shell/browser/api/electron_api_web_contents.h b/shell/browser/api/electron_api_web_contents.h index 9ae4a7c878ce..0e2ebb3a62d0 100644 --- a/shell/browser/api/electron_api_web_contents.h +++ b/shell/browser/api/electron_api_web_contents.h @@ -709,6 +709,7 @@ class WebContents final : public ExclusiveAccessContext, content::PictureInPictureResult EnterPictureInPicture( content::WebContents* web_contents) override; void ExitPictureInPicture() override; + bool ShouldFocusPageAfterCrash(content::WebContents* source) override; // InspectableWebContentsDelegate: void DevToolsSaveToFile(const std::string& url, diff --git a/spec/webview-spec.ts b/spec/webview-spec.ts index dfc30937706e..23d07e32569d 100644 --- a/spec/webview-spec.ts +++ b/spec/webview-spec.ts @@ -1895,6 +1895,28 @@ describe(' tag', function () { expect(channel).to.equal('onbeforeunload'); }); + + it('does not crash when renderer process crashes', async function () { + // It takes more time to wait for the rendering process to crash + this.timeout(120000); + await loadWebView(w, { + nodeintegration: 'on', + webpreferences: 'contextIsolation=no', + src: blankPageUrl + }); + // Create a crash in the rendering process of a webview + await w.executeJavaScript(`new Promise((resolve, reject) => { + webview.addEventListener('render-process-gone', (e) => resolve({...e}), {once: true}) + webview.executeJavaScript('process.crash()', true) + })`); + // Reload the webview and the main process will not crash. + await w.executeJavaScript(`new Promise((resolve, reject) => { + webview.reload() + webview.addEventListener('did-finish-load', () => { + resolve() + }) + })`); + }); }); describe('.goForward()', () => {