
    (Gj                    l    d Z ddlmZ ddlZddlZddlmZ  ej        e          Z	e
eefZdd	ZddZdS )u  Suppress benign event-loop teardown noise on the gateway serving loop.

When the Desktop client forcibly closes its WebSocket while the gateway still
has pending socket operations, asyncio's transport teardown logs a full
traceback for every pending ``_call_connection_lost`` callback. On Windows this
surfaces as ``ConnectionResetError: [WinError 10054]`` (and the rarer
``ConnectionAbortedError: [WinError 10053]``); on POSIX it is the equivalent
``ConnectionResetError``/``BrokenPipeError``. A single client disconnect can
emit 50+ identical tracebacks into ``errors.log`` (#50005).

These are not actionable — they are the expected side effect of the peer
hanging up before our writes drained. We install a loop exception handler that
collapses exactly this class of teardown error to one debug line and forwards
everything else to asyncio's default handler unchanged, so genuine loop bugs
still surface.
    )annotationsN)Anycontextdict[str, Any]returnboolc                    |                      d          }t          |t                    sdS |                      d          }|                      d          }d}|t          |          v p|t          |          v S )u>  True when the loop error is a peer-hangup during transport teardown.

    Gated on BOTH the exception type AND the ``_call_connection_lost``
    callback so we only swallow the disconnect flood — any other place these
    errors surface (a real handler, a custom callback) still goes to the
    default handler.
    	exceptionFcallbackhandle_call_connection_lost)get
isinstance_BENIGN_TEARDOWN_ERRORSrepr)r   excr   r   markers        </home/rurouni/.hermes/hermes-agent/tui_gateway/loop_noise.py_is_benign_teardownr   #   sw     ++k
"
"Cc233 u {{:&&H[[""F$FT(^^#=vf'==    loopasyncio.AbstractEventLoopNonec                    t          | dd          rdS |                                 dfd
}|                     |           	 d| _        dS # t          t
          f$ r Y dS w xY w)zChain a teardown-noise filter ahead of the loop's existing handler.

    Idempotent: re-installing on a loop that already has the filter is a no-op,
    so it's safe to call on every reconnect/serve entry.
    _hermes_noise_filter_installedFNr   r   r   r   r   r   c                    t          |          r0t                              d|                    d                     d S  | |           d S |                     |           d S )Nz/ws peer hangup during teardown (suppressed): %sr
   )r   _logdebugr   default_exception_handler)r   r   previouss     r   _handlerz+install_loop_noise_filter.<locals>._handlerA   sz    w'' 	JJAK((   FHT7#####**733333r   T)r   r   r   r   r   r   )getattrget_exception_handlerset_exception_handlerr   AttributeError	TypeError)r   r!   r    s     @r   install_loop_noise_filterr'   6   s     t5u== ))++H
4 
4 
4 
4 
4 
4 	x(((.2+++I&   s   A A#"A#)r   r   r   r   )r   r   r   r   )__doc__
__future__r   asynciologgingtypingr   	getLogger__name__r   ConnectionResetErrorConnectionAbortedErrorBrokenPipeErrorr   r   r'    r   r   <module>r3      s    " # " " " " "        w""
  > > > >&     r   