diff --git a/shell/browser/api/electron_api_view.cc b/shell/browser/api/electron_api_view.cc index 661347396826..4ddf0badd98a 100644 --- a/shell/browser/api/electron_api_view.cc +++ b/shell/browser/api/electron_api_view.cc @@ -216,6 +216,12 @@ void View::AddChildViewAt(gin::Handle child, if (!view_) return; + if (!child->view()) { + gin_helper::ErrorThrower(isolate()).ThrowError( + "Can't add a destroyed child view to a parent view"); + return; + } + // This will CHECK and crash in View::AddChildViewAtImpl if not handled here. if (view_ == child->view()) { gin_helper::ErrorThrower(isolate()).ThrowError( diff --git a/spec/api-web-contents-view-spec.ts b/spec/api-web-contents-view-spec.ts index 077cb96e30d7..63f45c140edd 100644 --- a/spec/api-web-contents-view-spec.ts +++ b/spec/api-web-contents-view-spec.ts @@ -55,6 +55,20 @@ describe('WebContentsView', () => { })).to.throw('options.webContents is already attached to a window'); }); + it('should throw an error when adding a destroyed child view to the parent view', async () => { + const browserWindow = new BrowserWindow(); + + const webContentsView = new WebContentsView(); + webContentsView.webContents.loadURL('about:blank'); + webContentsView.webContents.destroy(); + + const destroyed = once(webContentsView.webContents, 'destroyed'); + await destroyed; + expect(() => browserWindow.contentView.addChildView(webContentsView)).to.throw( + 'Can\'t add a destroyed child view to a parent view' + ); + }); + it('should throw error when created with already attached webContents to other WebContentsView', () => { const browserWindow = new BrowserWindow();