@@ -219,19 +219,24 @@ async def _forward_io(ws, screen, stream):
219219
220220 async def _read_ws ():
221221 nonlocal exit_code
222- async for raw_msg in ws :
223- msg = json .loads (raw_msg )
224- if msg .get ("data" ):
225- # Convert bare \n to \r\n before feeding pyte, equivalent
226- # to xterm.js ``convertEol: true``.
227- stream .feed (msg ["data" ].replace ("\n " , "\r \n " ))
228- _render_dirty (screen , sys .stdout .buffer )
229- elif msg .get ("error" ):
230- stream .feed (f"Error: { msg ['error' ]} \r \n " )
231- _render_dirty (screen , sys .stdout .buffer )
232- if "Code" in msg :
233- exit_code = msg ["Code" ]
234- return
222+ try :
223+ async for raw_msg in ws :
224+ msg = json .loads (raw_msg )
225+ if msg .get ("data" ):
226+ # pyte expects \r\n; remote PTY may send bare \n
227+ # (same as xterm.js ``convertEol: true``).
228+ stream .feed (msg ["data" ].replace ("\n " , "\r \n " ))
229+ _render_dirty (screen , sys .stdout .buffer )
230+ elif msg .get ("error" ):
231+ stream .feed (f"Error: { msg ['error' ]} \r \n " )
232+ _render_dirty (screen , sys .stdout .buffer )
233+ if "Code" in msg :
234+ exit_code = msg ["Code" ]
235+ return
236+ except websockets .ConnectionClosed :
237+ # Backend proxy may not send a clean close frame when
238+ # ArgoCD disconnects after the remote shell exits.
239+ return
235240
236241 async def _read_stdin ():
237242 read_queue = asyncio .Queue ()
@@ -250,16 +255,19 @@ def _on_stdin_ready():
250255 data = await asyncio .wait_for (read_queue .get (), timeout = 0.5 )
251256 except asyncio .TimeoutError :
252257 continue
253- await ws .send (
254- json .dumps (
255- {
256- "operation" : "stdin" ,
257- "data" : data .decode ("utf-8" , errors = "replace" ),
258- "rows" : screen .lines ,
259- "cols" : screen .columns ,
260- }
258+ try :
259+ await ws .send (
260+ json .dumps (
261+ {
262+ "operation" : "stdin" ,
263+ "data" : data .decode ("utf-8" , errors = "replace" ),
264+ "rows" : screen .lines ,
265+ "cols" : screen .columns ,
266+ }
267+ )
261268 )
262- )
269+ except websockets .ConnectionClosed :
270+ return
263271 finally :
264272 loop .remove_reader (stdin_fd )
265273
0 commit comments