
    ci~                         d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
mZmZ ddlZddlmZ ddlmZ ddlmZmZ  G d d	e      Z G d
 de      Zy)zMExceptionToStatusInterceptor catches GrpcException and sets the gRPC context.    )contextmanager)	AnyAsyncGeneratorAsyncIterableCallable	GeneratorIterableIteratorNoReturnOptionalN)aio)GrpcException)AsyncServerInterceptorServerInterceptorc                      e Zd ZdZddeej                     fdZdedej                  de
ded	eeddf   f
d
Zededej                  de
d	ed   fd       Zdededej                  de
d	ef
dZdededej                  de
d	ef
dZy)ExceptionToStatusInterceptora;  An interceptor that catches exceptions and sets the RPC status and details.

    ExceptionToStatusInterceptor will catch any subclass of GrpcException and set the
    status code and details on the gRPC context. You can also extend this and override
    the handle_exception method to catch other types of exceptions, and handle them in
    different ways. E.g., you can catch and handle exceptions that don't derive from
    GrpcException. Or you can set rich error statuses with context.abort_with_status().

    Args:
        status_on_unknown_exception: Specify what to do if an exception which is
            not a subclass of GrpcException is raised. If None, do nothing (by
            default, grpc will set the status to UNKNOWN). If not None, then the
            status code will be set to this value if `context.abort` hasn't been called
            earlier. It must not be OK. The details will be set to the value of repr(e),
            where e is the exception. In any case, the exception will be propagated.

    Raises:
        ValueError: If status_code is OK.
    Nstatus_on_unknown_exceptionc                 b    |t         j                  j                  k(  rt        d      || _        y Nz3The status code for unknown exceptions cannot be OKgrpc
StatusCodeOK
ValueError_status_on_unknown_exceptionselfr   s     K/tmp/pip-target-z3e9_cxr/lib/python/grpc_interceptor/exception_to_status.py__init__z%ExceptionToStatusInterceptor.__init__-   (    &$//*<*<<RSS,G)    request_or_iteratorcontextmethod_nameresponse_iteratorreturnc              #   t   K   | j                  |||      5  |E d{    ddd       y7 # 1 sw Y   yxY wwz<Yield all the responses, but check for errors along the way.N)_handle_exception)r   r"   r#   r$   r%   s        r   _generate_responsesz0ExceptionToStatusInterceptor._generate_responses3   sA      ##$7+N 	)(((	) 	)(	) 	)s    8,*,	8,58c              #   j   K   	 d  y # t         $ r}| j                  ||||       Y d }~y d }~ww xY wwN	Exceptionhandle_exception)r   r"   r#   r$   exs        r   r)   z.ExceptionToStatusInterceptor._handle_exception>   s8     	Q 	Q!!"&97KPP	Qs    3	 3	0+303r0   c                     t        |t              r(|j                  |j                  |j                         ||j                         s1| j                  %|j                  | j                  t        |             |)  Override this if extending ExceptionToStatusInterceptor.

        This will get called when an exception is raised while handling the RPC.

        Args:
            ex: The exception that was raised.
            request_or_iterator: The RPC request, as a protobuf message if it is a
                unary request, or an iterator of protobuf messages if it is a streaming
                request.
            context: The servicer context. You probably want to call context.abort(...)
            method_name: The name of the RPC being called.

        Raises:
            This method must raise and cannot return, as in general there's no
            meaningful RPC response to return if an exception has occurred. You can
            raise the original exception, ex, or something else.
        
isinstancer   abortstatus_codedetailscoder   reprr   r0   r"   r#   r$   s        r   r/   z-ExceptionToStatusInterceptor.handle_exceptionG   s_    0 b-(MM".."**5  00<d??bJr!   methodc                     | j                  |||      5   |||      }ddd       t        t              r| j                  ||||      S |S # 1 sw Y   /xY w)FDo not call this directly; use the interceptor kwarg on grpc.server().N)r)   r4   r	   r*   )r   r;   r"   r#   r$   response_or_iterators         r   	interceptz&ExceptionToStatusInterceptor.interceptf   sp     ##$7+N 	H#)*=w#G 	H *H5++#Wk;O 
 ('	H 	Hs   
AAr,   )__name__
__module____qualname____doc__r   r   r   r   r   ServicerContextstrr	   r   r*   r   r
   r)   r.   r   r/   r   r?    r!   r   r   r      s   (HHT__4M H	) 	) %%	) 		)
 $	) 
3d?	#	) Q#&Q151E1EQTWQ	$Q Q ! %%	
  
>(( !( %%	(
 ( 
(r!   r   c                       e Zd ZdZddeej                     fdZdede	j                  deded	eedf   f
d
Zdedede	j                  ded	ef
dZdedede	j                  ded	ef
dZy)!AsyncExceptionToStatusInterceptorzAn interceptor that catches exceptions and sets the RPC status and details.

    This is the async analogy to ExceptionToStatusInterceptor. Please see that class'
    documentation for more information.
    Nr   c                 b    |t         j                  j                  k(  rt        d      || _        y r   r   r   s     r   r   z*AsyncExceptionToStatusInterceptor.__init__   r    r!   r"   r#   r$   r%   r&   c                   K   	 |2 3 d{   }| 7 
6 y# t         $ r'}| j                  ||||       d{  7   Y d}~yd}~ww xY wwr(   r-   )r   r"   r#   r$   r%   rr0   s          r   r*   z5AsyncExceptionToStatusInterceptor._generate_responses   sU     	W,  a, 	W'',?+VVV	WsJ   A   A	A	A<AAA		Ar0   c                 (  K   t        |t              r0|j                  |j                  |j                         d{    ||j                         s9| j                  -|j                  | j                  t        |             d{    |7 Q7 w)r2   Nr3   r:   s        r   r/   z2AsyncExceptionToStatusInterceptor.handle_exception   s{     0 b-(--

;;;  00<mmD$E$EtBxPPP	 < Qs"   :BBA
BBBBr;   c                    K   	  |||      }t        |d      s
| d{   S 	 | j                  |||      S 7 # t        $ r'}| j                  ||||       d{  7   Y d}~Ad}~ww xY ww)r=   	__aiter__N)hasattrr.   r/   r*   )r   r;   r"   r#   r$   r>   r0   s          r   r?   z+AsyncExceptionToStatusInterceptor.intercept   s     	W#)*=w#G /=111 >
 ''+7K
 	
	 2 	W'',?+VVV	WsC   A-: 8: A-: 	A*A%AA% A-%A**A-r,   )r@   rA   rB   rC   r   r   r   r   r   grpc_aiorD   rE   r   r   r*   r.   r   r/   r   r?   rF   r!   r   rH   rH   {   s    HHT__4M HW W ))W 	W
 )W 
T		"W ! ))	
  
>

 !
 ))	

 
 

r!   rH   )rC   
contextlibr   typingr   r   r   r   r   r	   r
   r   r   r   r   rP   grpc_interceptor.exceptionsr   grpc_interceptor.serverr   r   r   rH   rF   r!   r   <module>rU      sI    S &
 
 
    5 M`(#4 `(FK
(> K
r!   