2015-10-11 13 views
84

मैंने अभी अपनी स्क्रिप्टिंग भाषा के रूप में पायथन उठाया है और मैं यह समझने की कोशिश कर रहा हूं कि boto3 के साथ उचित त्रुटि कैसे करें।बोटो 3, पायथन और त्रुटियों को कैसे संभालना है

मैं एक IAM उपयोगकर्ता बनाने के लिए कोशिश कर रहा हूँ:

def create_user(username, iam_conn): 
    try: 
     user = iam_conn.create_user(UserName=username) 
     return user 
    except Exception as e: 
     return e 

जब create_user करने के लिए कॉल सफल होता है, मैं एक साफ वस्तु जिसमें API कॉल के HTTP स्थिति कोड और नव निर्मित उपयोगकर्ता के डेटा शामिल हो जाओ ।

उदाहरण:

{'ResponseMetadata': 
     {'HTTPStatusCode': 200, 
     'RequestId': 'omitted' 
     }, 
u'User': {u'Arn': 'arn:aws:iam::omitted:user/omitted', 
      u'CreateDate': datetime.datetime(2015, 10, 11, 17, 13, 5, 882000, tzinfo=tzutc()), 
      u'Path': '/', 
      u'UserId': 'omitted', 
      u'UserName': 'omitted' 
      } 
} 

यह महान काम करता है। लेकिन जब यह विफल हो जाता है (जैसे कि उपयोगकर्ता पहले से मौजूद है), तो मुझे बस botocore.exceptions.bientError का एक ऑब्जेक्ट मिलता है जो मुझे बताता है कि क्या गलत हुआ।

उदाहरण: ClientError ('कोई त्रुटि हुई (EntityAlreadyExists) जब CreateUser आपरेशन बुला:। पहले से ही छोड़े गए नाम के साथ उपयोगकर्ता मौजूद है',)

यह (AFAIK) बहुत मुश्किल से निपटने त्रुटि बनाता है क्योंकि मैं नहीं कर सकता केवल परिणामी http स्थिति कोड पर स्विच करें (उपयोगकर्ता के लिए 40 9 आईएएम के लिए एडब्ल्यूएस एपीआई दस्तावेज़ों के अनुसार पहले से मौजूद है)। इससे मुझे लगता है कि मुझे कुछ गलत तरीके से करना होगा। इष्टतम तरीका boto3 के लिए कभी अपवाद नहीं फेंकने के लिए होगा, लेकिन juts हमेशा एक ऑब्जेक्ट लौटाता है जो दर्शाता है कि एपीआई कॉल कैसे चला गया।

क्या कोई मुझे इस मुद्दे पर प्रबुद्ध कर सकता है या मुझे सही दिशा में इंगित कर सकता है?

बहुत बहुत धन्यवाद!

+1

एडब्ल्यूएस दस्तावेज़ http://botocore.readthedocs.io/en/latest/client_upgrades.html#error-handling –

उत्तर

177

अपवाद के भीतर निहित प्रतिक्रिया का उपयोग करें।

  • ['Error']['Code'] उदहारण के लिए:

    import boto3 
    from botocore.exceptions import ClientError 
    
    try: 
        iam = boto3.client('iam') 
        user = iam.create_user(UserName='fred') 
        print "Created user: %s" % user 
    except ClientError as e: 
        if e.response['Error']['Code'] == 'EntityAlreadyExists': 
         print "User already exists" 
        else: 
         print "Unexpected error: %s" % e 
    

    अपवाद में प्रतिक्रिया dict निम्नलिखित शामिल होंगे: यहाँ एक उदाहरण है 'EntityAlreadyExists' या 'ValidationError'

  • ['ResponseMetadata']['HTTPStatusCode'] उदा। 400
  • ['ResponseMetadata']['RequestId'] उदा। 'd2b06652-88d7-11e5-99d0-812348583a35'
  • ['Error']['Message'] उदा। "एक त्रुटि हुई (EntityAlreadyExists) ..."
  • ['Error']['Type'] उदा। 'प्रेषक'

अधिक जानकारी के लिए botocore error handling देखें।

[अपडेट किया गया: 2018/03/07]

एडब्ल्यूएस अजगर एसडीके clients पर सेवा अपवाद बेनकाब करने के लिए शुरू हो गया है (हालांकि पर resources नहीं) है कि आप स्पष्ट रूप से, पकड़ कर सकते हैं तो यह अब संभव है लिखने के लिए उस कोड को कुछ ऐसा:

import boto3 
from botocore.exceptions import ClientError, ParamValidationError 

try: 
    iam = boto3.client('iam') 
    user = iam.create_user(UserName='fred') 
    print "Created user: %s" % user 
except iam.exceptions.EntityAlreadyExistsException: 
    print "User already exists" 
except ParamValidationError as e: 
    print "Parameter validation error: %s" % e 
except ClientError as e: 
    print "Unexpected error: %s" % e 

दुर्भाग्यवश, वर्तमान में इन अपवादों के लिए कोई दस्तावेज़ीकरण नहीं है।

-2

आपको समस्या को संभालने में विफल होने पर कुछ करने की आवश्यकता है। अभी आप वास्तविक अपवाद लौट रहे हैं। उदाहरण के लिए, यदि यह कोई समस्या नहीं है कि उपयोगकर्ता पहले से मौजूद है और आप इसे get_or_create फ़ंक्शन के रूप में उपयोग करना चाहते हैं, तो आप मौजूदा उपयोगकर्ता ऑब्जेक्ट को वापस कर समस्या को संभाल सकते हैं।

try: 
    user = iam_conn.create_user(UserName=username) 
    return user 
except botocore.exceptions.ClientError as e: 

    #this exception could actually be other things other than exists, so you want to evaluate it further in your real code. 
    if e.message.startswith(
     'enough of the exception message to identify it as the one you want') 

     print('that user already exists.') 
     user = iam_conn.get_user(UserName=username) 
     return user 

    elif e.message.some_other_condition: 

     #something else 
    else: 
     #unhandled ClientError 
     raise(e) 
except SomeOtherExceptionTypeYouCareAbout as e: 
    #handle it 

# any unhandled exception will raise here at this point. 
# if you want a general handler 

except Exception as e: 
    #handle it. 

कहा यही कारण है, शायद यह अपने अनुप्रयोग के लिए एक समस्या है, जो मामले में आप कोड है कि अपने उपयोगकर्ता समारोह बना सकते हैं और फोन करने के समारोह का निर्धारण से निपटने के लिए कैसे करते हैं कहा जाता है चारों ओर अपवाद संचालक रखना चाहते हैं करना चाहते हैं उदाहरण के लिए, उपयोगकर्ता को अन्य उपयोगकर्ता नाम इनपुट करने के लिए कहकर, या जो भी आपके आवेदन के लिए समझ में आता है।

+0

लेकिन उपयोगकर्ता पहले से मौजूद है, केवल एपीआई कॉल विफल हो सकता है। मुझे इस विधि के साथ इन दोनों के बीच अंतर करने का कोई तरीका नहीं दिख रहा है। – SQDK

+0

बस आधार स्तर पर अपवाद हैंडलिंग कैसे काम करता है यह बताता है कि ऐसा लगता है कि भ्रम कहां है। मैंने उस प्रभाव पर एक टिप्पणी की। – tlastowka

+0

इसके लिए धन्यवाद। यह केवल मेरे संदेह को लागू करता है कि यह प्रश्न अधिक boto3-विशिष्ट है जो पायथन-विशिष्ट है। मुझे अजगर में त्रुटि प्रबंधन के लिए सामान्य पैटर्न से अवगत नहीं है, इसलिए प्रश्न पूछने का मेरा सामान्य तरीका – SQDK

0

या कक्षा के नाम पर तुलना उदा।

except ClientError as e: 
    if 'EntityAlreadyExistsException' == e.__class__.__name__: 
     # handle specific error 

क्योंकि वे गतिशील रूप से बनाए गए हैं, आप कक्षा को कभी भी आयात नहीं कर सकते हैं और वास्तविक पायथन का उपयोग करके इसे पकड़ सकते हैं।

+0

तो मैं 'अपवाद को छोड़कर' के साथ सभी अपवादों को पकड़ रहा हूं और फिर यदि विशिष्ट अपवाद निर्धारित करने के लिए बयान हैं? विशिष्ट अपवादों को पकड़ने से अलग/बेहतर कैसे है? इसकी और रेखाएं, और आपको कक्षा नाम प्राप्त करने के लिए लाइब्रेरी आयात करने की आवश्यकता होगी। जब तक आप अपवाद नाम हार्डकोडिंग के साथ नहीं जाना चाहते हैं। सब कुछ, यह इसके बारे में जाने का एक बुरा तरीका लगता है। – SQDK

+0

@ एसक्यूडीके क्षमा करें मेरा जवाब अस्पष्ट था, लेकिन आप किस बारे में बात नहीं कर रहे हैं। मैंने इसे अपडेट किया है। – jmoz

संबंधित मुद्दे