o
    i.                     @   s   d Z ddlZddlZddlZddlmZ ddlmZ ddlZddl	m
Z
 ddlmZ ddlmZ dd	lmZmZmZ G d
d deZG dd deZdS )zFError handling middleware for consistent error responses and tracking.    N)Callable)Any)McpError)	ErrorData)NotFoundError   )CallNext
MiddlewareMiddlewareContextc                	   @   s   e Zd ZdZ				ddejdB dedeee	gdf dB defd	d
Z
dede	ddfddZdedefddZde	dedefddZdeeef fddZdS )ErrorHandlingMiddlewarea*  Middleware that provides consistent error handling and logging.

    Catches exceptions, logs them appropriately, and converts them to
    proper MCP error responses. Also tracks error patterns for monitoring.

    Example:
        ```python
        from fastmcp.server.middleware.error_handling import ErrorHandlingMiddleware
        import logging

        # Configure logging to see error details
        logging.basicConfig(level=logging.ERROR)

        mcp = FastMCP("MyServer")
        mcp.add_middleware(ErrorHandlingMiddleware())
        ```
    NFTloggerinclude_tracebackerror_callbacktransform_errorsc                 C   s,   |pt d| _|| _|| _|| _i | _dS )a}  Initialize error handling middleware.

        Args:
            logger: Logger instance for error logging. If None, uses 'fastmcp.errors'
            include_traceback: Whether to include full traceback in error logs
            error_callback: Optional callback function called for each error
            transform_errors: Whether to transform non-MCP errors to McpError
        zfastmcp.errorsN)logging	getLoggerr   r   r   r   error_counts)selfr   r   r   r    r   n/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/fastmcp/server/middleware/error_handling.py__init__%   s
   
z ErrorHandlingMiddleware.__init__errorcontextreturnc              
   C   s   t |j}|jp	d}| d| }| j|dd | j|< d| d| d|}| jr9| j| dt	   n| j| | j
rhz	| 
|| W d	S  tyg } z| jd|  W Y d	}~d	S d	}~ww d	S )
z(Log error with appropriate detail level.unknown:r   r   z	Error in : 
zError in error callback: N)type__name__methodr   getr   r   r   	traceback
format_excr   	Exception)r   r   r   
error_typer    	error_keybase_messagecallback_errorr   r   r   
_log_error:   s    

 z"ErrorHandlingMiddleware._log_errorc                 C   s   t |tr|S | js|S t|}|ttfv r!ttdd|dS |ttt	fv r3ttdd|dS |t
u rBttdd|dS |ttjfv rTttdd|dS ttd	d
|dS )z.Transform non-MCP errors to proper MCP errors.izInvalid params: )codemessageizResource not found: i zPermission denied: zRequest timeout: izInternal error: )
isinstancer   r   r   
ValueError	TypeErrorr   FileNotFoundErrorKeyErrorr   PermissionErrorTimeoutErrorasyncio)r   r   r%   r   r   r   _transform_errorQ   s0   
z(ErrorHandlingMiddleware._transform_error	call_nextc              
      sH   z||I dH W S  t y# } z| || | |}||d}~ww )zHandle errors for all messages.N)r$   r)   r4   )r   r   r5   r   transformed_errorr   r   r   
on_messager   s   
z"ErrorHandlingMiddleware.on_messagec                 C   s
   | j  S )z$Get error statistics for monitoring.)r   copy)r   r   r   r   get_error_stats}   s   
z'ErrorHandlingMiddleware.get_error_stats)NFNT)r   
__module____qualname____doc__r   Loggerboolr   r$   r
   r   r)   r4   r   r   r7   dictstrintr9   r   r   r   r   r      s&    
!r   c                   @   s   e Zd ZdZddddeefdfdeded	ed
edee	e
 df dejdB fddZde
defddZdedefddZdededefddZdS )RetryMiddlewareai  Middleware that implements automatic retry logic for failed requests.

    Retries requests that fail with transient errors, using exponential
    backoff to avoid overwhelming the server or external dependencies.

    Example:
        ```python
        from fastmcp.server.middleware.error_handling import RetryMiddleware

        # Retry up to 3 times with exponential backoff
        retry_middleware = RetryMiddleware(
            max_retries=3,
            retry_exceptions=(ConnectionError, TimeoutError)
        )

        mcp = FastMCP("MyServer")
        mcp.add_middleware(retry_middleware)
        ```
       g      ?g      N@g       @Nmax_retries
base_delay	max_delaybackoff_multiplierretry_exceptions.r   c                 C   s2   || _ || _|| _|| _|| _|ptd| _dS )a  Initialize retry middleware.

        Args:
            max_retries: Maximum number of retry attempts
            base_delay: Initial delay between retries in seconds
            max_delay: Maximum delay between retries in seconds
            backoff_multiplier: Multiplier for exponential backoff
            retry_exceptions: Tuple of exception types that should trigger retries
            logger: Logger for retry attempts
        zfastmcp.retryN)rD   rE   rF   rG   rH   r   r   r   )r   rD   rE   rF   rG   rH   r   r   r   r   r      s   zRetryMiddleware.__init__r   r   c                 C   s   t || jS )z-Determine if an error should trigger a retry.)r,   rH   )r   r   r   r   r   _should_retry   s   zRetryMiddleware._should_retryattemptc                 C   s   | j | j|  }t|| jS )z-Calculate delay for the given attempt number.)rE   rG   minrF   )r   rJ   delayr   r   r   _calculate_delay   s   z RetryMiddleware._calculate_delayr   r5   c                    s   d}t | jd D ]a}z
||I dH W   S  tyk } zI|}|| jks*| |s1W Y d}~ n;| |}| jd|j d|d  d| jd  dt|j	 d|d|d	d
 t
|I dH  W Y d}~q
d}~ww |rp|dS )z#Implement retry logic for requests.Nr   zRequest z failed (attempt /z): r   z. Retrying in z.1fzs...)rangerD   r$   rI   rM   r   warningr    r   r   anyiosleep)r   r   r5   
last_errorrJ   r   rL   r   r   r   
on_request   s2   
 zRetryMiddleware.on_request)r   r:   r;   r<   ConnectionErrorr2   rA   floattupler   r$   r   r=   r   r>   rI   rM   r
   r   r   rT   r   r   r   r   rB      s0    
rB   )r<   r3   r   r"   collections.abcr   typingr   rQ   mcpr   	mcp.typesr   fastmcp.exceptionsr   
middlewarer   r	   r
   r   rB   r   r   r   r   <module>   s    p