1# Copyright 2019 The gRPC Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""This example handles rich error status in client-side.""" 15 16from __future__ import print_function 17import logging 18 19import grpc 20from grpc_status import rpc_status 21from google.rpc import error_details_pb2 22 23from examples import helloworld_pb2 24from examples import helloworld_pb2_grpc 25 26_LOGGER = logging.getLogger(__name__) 27 28 29def process(stub): 30 try: 31 response = stub.SayHello(helloworld_pb2.HelloRequest(name='Alice')) 32 _LOGGER.info('Call success: %s', response.message) 33 except grpc.RpcError as rpc_error: 34 _LOGGER.error('Call failure: %s', rpc_error) 35 status = rpc_status.from_call(rpc_error) 36 for detail in status.details: 37 if detail.Is(error_details_pb2.QuotaFailure.DESCRIPTOR): 38 info = error_details_pb2.QuotaFailure() 39 detail.Unpack(info) 40 _LOGGER.error('Quota failure: %s', info) 41 else: 42 raise RuntimeError('Unexpected failure: %s' % detail) 43 44 45def main(): 46 # NOTE(gRPC Python Team): .close() is possible on a channel and should be 47 # used in circumstances in which the with statement does not fit the needs 48 # of the code. 49 with grpc.insecure_channel('localhost:50051') as channel: 50 stub = helloworld_pb2_grpc.GreeterStub(channel) 51 process(stub) 52 53 54if __name__ == '__main__': 55 logging.basicConfig() 56 main() 57