@ -42,6 +42,8 @@ cdef class RPCState:
self . abort_exception = None
self . metadata_sent = False
self . status_sent = False
self . status_code = StatusCode . ok
self . status_details = ' '
self . trailing_metadata = _IMMUTABLE_EMPTY_METADATA
cdef bytes method ( self ) :
@ -143,6 +145,9 @@ cdef class _ServicerContext:
if trailing_metadata == _IMMUTABLE_EMPTY_METADATA and self . _rpc_state . trailing_metadata :
trailing_metadata = self . _rpc_state . trailing_metadata
if details == ' ' and self . _rpc_state . status_details :
details = self . _rpc_state . status_details
actual_code = get_status_code ( code )
self . _rpc_state . status_sent = True
@ -163,6 +168,12 @@ cdef class _ServicerContext:
def invocation_metadata ( self ) :
return self . _rpc_state . invocation_metadata ( )
def set_code ( self , object code ) :
self . _rpc_state . status_code = get_status_code ( code )
def set_details ( self , str details ) :
self . _rpc_state . status_details = details
cdef _find_method_handler ( str method , tuple metadata , list generic_handlers ) :
cdef _HandlerCallDetails handler_call_details = _HandlerCallDetails ( method ,
@ -209,8 +220,8 @@ async def _finish_handler_with_unary_response(RPCState rpc_state,
SendMessageOperation ( response_raw , _EMPTY_FLAGS ) ,
SendStatusFromServerOperation (
rpc_state . trailing_metadata ,
StatusCode . ok ,
b ' ' ,
rpc_state . status_code ,
rpc_state . status_details ,
_EMPTY_FLAGS ,
) ,
)
@ -262,8 +273,8 @@ async def _finish_handler_with_stream_responses(RPCState rpc_state,
# Sends the final status of this RPC
cdef SendStatusFromServerOperation op = SendStatusFromServerOperation (
rpc_state . trailing_metadata ,
StatusCode . ok ,
b ' ' ,
rpc_state . status_code ,
rpc_state . status_details ,
_EMPTY_FLAGS ,
)
@ -419,11 +430,20 @@ async def _handle_exceptions(RPCState rpc_state, object rpc_coro, object loop):
except _ServerStoppedError :
_LOGGER . info ( ' Aborting RPC due to server stop. ' )
except Exception as e :
_LOGGER . exception ( e )
_LOGGER . exception ( ' Unexpected [ %s ] raised by servicer method [ %s ] ' % (
type ( e ) . __name__ ,
_decode ( rpc_state . method ( ) ) ,
) )
if not rpc_state . status_sent and rpc_state . server . _status != AIO_SERVER_STATUS_STOPPED :
# Allows users to raise other types of exception with specified status code
if rpc_state . status_code == StatusCode . ok :
status_code = StatusCode . unknown
else :
status_code = rpc_state . status_code
await _send_error_status_from_server (
rpc_state ,
StatusCode . unknown ,
status_code ,
' Unexpected %s : %s ' % ( type ( e ) , e ) ,
rpc_state . trailing_metadata ,
rpc_state . metadata_sent ,