Repository: electron/electron (language: cpp)

Issue:
[Docs] Wrong usage of ipcMain.handle in /tutorial-preload
This is a repost of #35157 . That issue is closed as fixed, but the merged pull request seems to fix a different unrelated issue.

### Steps to Reproduce:

1. Follow tutorial on macOS, including section "Open a window if none are open (macOS)" from [Part 2](https://www.electronjs.org/docs/latest/tutorial/tutorial-first-app#managing-your-apps-window-lifecycle).
2. Build and launch the app.
3. Close the window, open another window.

### Expected Behavior:

- A new window launches without error.

### Actual Behavior:

- An error is thrown and the window launches blank.
![image](https://user-images.githubusercontent.com/13035830/235337714-fc9496dc-b735-42b4-b981-9f8d8d72da55.png)

This is because `icpMain.handle()` is being called every time a window is created (which can be multiple times on macOS) instead of just once (i.e. inside of `app.whenReady()`)

https://github.com/electron/electron/blob/a2d35e9cf53f324d8153cb56982074e1af5fb177/docs/tutorial/tutorial-3-preload.md?plain=1#L209-L220


Discussion / hints:

Fix patch:
diff --git a/docs/tutorial/tutorial-3-preload.md b/docs/tutorial/tutorial-3-preload.md
index 97c45780e354c..2074d3c5152c9 100644
--- a/docs/tutorial/tutorial-3-preload.md
+++ b/docs/tutorial/tutorial-3-preload.md
@@ -202,7 +202,7 @@ Then, set up your `handle` listener in the main process. We do this _before_
 loading the HTML file so that the handler is guaranteed to be ready before
 you send out the `invoke` call from the renderer.
 
-```js {1,12} title="main.js"
+```js {1,15} title="main.js"
 const { app, BrowserWindow, ipcMain } = require('electron')
 const path = require('path')
 
@@ -214,10 +214,12 @@ const createWindow = () => {
       preload: path.join(__dirname, 'preload.js'),
     },
   })
-  ipcMain.handle('ping', () => 'pong')
   win.loadFile('index.html')
 }
-app.whenReady().then(createWindow)
+app.whenReady().then(() => {
+  ipcMain.handle('ping', () => 'pong')
+  createWindow()
+})
 ```
 
 Once you have the sender and receiver set up, you can now send messages from the renderer


Test patch: