मैं सॉल्टस्टैक के लिए कुछ आदि मॉड्यूल लिख रहा था और इस अजीब मुद्दे में भाग गया जहां यह मुझे किसी अपवाद को पकड़ने से रोक रहा है और मुझे इसमें दिलचस्पी है कि यह कैसा चल रहा है। ऐसा लगता है कि विशेष रूप से urllib3 के आसपास केंद्रित है।मैं इस पायथन अपवाद को क्यों नहीं पकड़ सकता?
एक छोटा सा स्क्रिप्ट (नहीं नमक):
import etcd
c = etcd.Client('127.0.0.1', 4001)
print c.read('/test1', wait=True, timeout=2)
और जब हम इसे चलाने:
[[email protected] utils]# /tmp/etcd_watch.py
Traceback (most recent call last):
File "/tmp/etcd_watch.py", line 5, in <module>
print c.read('/test1', wait=True, timeout=2)
File "/usr/lib/python2.6/site-packages/etcd/client.py", line 481, in read
timeout=timeout)
File "/usr/lib/python2.6/site-packages/etcd/client.py", line 788, in api_execute
cause=e
etcd.EtcdConnectionFailed: Connection to etcd failed due to ReadTimeoutError("HTTPConnectionPool(host='127.0.0.1', port=4001): Read timed out.",)
ठीक है, चलो कि मैथुन पकड़ने करते हैं:
#!/usr/bin/python
import etcd
c = etcd.Client('127.0.0.1', 4001)
try:
print c.read('/test1', wait=True, timeout=2)
except etcd.EtcdConnectionFailed:
print 'connect failed'
भागो यह:
[[email protected] _modules]# /tmp/etcd_watch.py
connect failed
अच्छा लगता है - यह सब काम कर रहे अजगर है। तो क्या मुद्दा है? मैं नमक etcd मॉड्यूल में इस है:
[[email protected] _modules]# cat sjmh.py
import etcd
def test():
c = etcd.Client('127.0.0.1', 4001)
try:
return c.read('/test1', wait=True, timeout=2)
except etcd.EtcdConnectionFailed:
return False
और जब हम चलने वाले:
[[email protected] _modules]# salt 'alpha' sjmh.test
alpha:
The minion function caused an exception: Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/salt/minion.py", line 1173, in _thread_return
return_data = func(*args, **kwargs)
File "/var/cache/salt/minion/extmods/modules/sjmh.py", line 5, in test
c.read('/test1', wait=True, timeout=2)
File "/usr/lib/python2.6/site-packages/etcd/client.py", line 481, in read
timeout=timeout)
File "/usr/lib/python2.6/site-packages/etcd/client.py", line 769, in api_execute
_ = response.data
File "/usr/lib/python2.6/site-packages/urllib3/response.py", line 150, in data
return self.read(cache_content=True)
File "/usr/lib/python2.6/site-packages/urllib3/response.py", line 218, in read
raise ReadTimeoutError(self._pool, None, 'Read timed out.')
ReadTimeoutError: HTTPConnectionPool(host='127.0.0.1', port=4001): Read timed out.
मानव संसाधन विकास मंत्री कि अजीब है। आदि के पढ़ने को वापस भेजना चाहिए था। etcdConnectionFailed। तो, चलो इसे आगे देखो। हमारे मॉड्यूल अब यह है:
import etcd
def test():
c = etcd.Client('127.0.0.1', 4001)
try:
return c.read('/test1', wait=True, timeout=2)
except Exception as e:
return str(type(e))
और हम पाते हैं:
[[email protected] _modules]# salt 'alpha' sjmh.test
alpha:
<class 'urllib3.exceptions.ReadTimeoutError'>
ठीक है, इसलिए हम जानते हैं कि हम इस बात पकड़ कर सकते हैं। और अब हम जानते हैं कि इसे रीडटाइम एरर फेंक दिया गया है, तो चलिए इसे पकड़ लें। हमारे मॉड्यूल के नवीनतम संस्करण:
import etcd
import urllib3.exceptions
def test():
c = etcd.Client('127.0.0.1', 4001)
try:
c.read('/test1', wait=True, timeout=2)
except urllib3.exceptions.ReadTimeoutError as e:
return 'caught ya!'
except Exception as e:
return str(type(e))
और हमारे परीक्षण ..
[[email protected] _modules]# salt 'alpha' sjmh.test
alpha:
<class 'urllib3.exceptions.ReadTimeoutError'>
एर, रुको, क्या? हमने उसे क्यों नहीं पकड़ा? अपवाद काम करते हैं, है ना?
कैसे के बारे में अगर हम कोशिश करते हैं और urllib3 से आधार वर्ग को पकड़ने ..
[[email protected] _modules]# cat sjmh.py
import etcd
import urllib3.exceptions
def test():
c = etcd.Client('127.0.0.1', 4001)
try:
c.read('/test1', wait=True, timeout=2)
except urllib3.exceptions.HTTPError:
return 'got you this time!'
आशा और प्रार्थना करता हूँ ..
[[email protected] _modules]# salt 'alpha' sjmh.test
alpha:
The minion function caused an exception: Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/salt/minion.py", line 1173, in _thread_return
return_data = func(*args, **kwargs)
File "/var/cache/salt/minion/extmods/modules/sjmh.py", line 7, in test
c.read('/test1', wait=True, timeout=2)
File "/usr/lib/python2.6/site-packages/etcd/client.py", line 481, in read
timeout=timeout)
File "/usr/lib/python2.6/site-packages/etcd/client.py", line 769, in api_execute
_ = response.data
File "/usr/lib/python2.6/site-packages/urllib3/response.py", line 150, in data
return self.read(cache_content=True)
File "/usr/lib/python2.6/site-packages/urllib3/response.py", line 218, in read
raise ReadTimeoutError(self._pool, None, 'Read timed out.')
ReadTimeoutError: HTTPConnectionPool(host='127.0.0.1', port=4001): Read timed out.
ब्लास्ट YE! ठीक है, आइए एक अलग विधि का प्रयास करें जो एक अलग आदि अपवाद देता है। हमारे मॉड्यूल अब इस तरह दिखता है:
import etcd
def test():
c = etcd.Client('127.0.0.1', 4001)
try:
c.delete('/')
except etcd.EtcdRootReadOnly:
return 'got you this time!'
और हमारे रन:
[[email protected] _modules]# salt 'alpha' sjmh.test
alpha:
got you this time!
एक अंतिम परीक्षण के रूप में, मैं इस मॉड्यूल है, जो मैं चला सकते हैं या तो सीधे अजगर से, या एक नमक मॉड्यूल के रूप में बनाया है। ।
import etcd
import urllib3
def test():
c = etcd.Client('127.0.0.1', 4001)
try:
c.read('/test1', wait=True, timeout=2)
except urllib3.exceptions.ReadTimeoutError:
return 'got you this time!'
except etcd.EtcdConnectionFailed:
return 'cant get away from me!'
except etcd.EtcdException:
return 'oh no you dont'
except urllib3.exceptions.HTTPError:
return 'get back here!'
except Exception as e:
return 'HOW DID YOU GET HERE? {0}'.format(type(e))
if __name__ == "__main__":
print test()
अजगर के माध्यम से:
[[email protected] _modules]# python ./sjmh.py
cant get away from me!
नमक के माध्यम से:
[[email protected] _modules]# salt 'alpha' sjmh.test
alpha:
HOW DID YOU GET HERE? <class 'urllib3.exceptions.ReadTimeoutError'>
तो, हम etcd से अपवाद पकड़ कर सकते हैं कि यह फेंकता है। लेकिन, जब हम आम तौर पर urllib3 को पकड़ने में सक्षम होते हैं, जब हम अपने अकेले द्वारा पायथन-आदि चलाते हैं, जब मैं इसे नमक के माध्यम से चलाता हूं, तो कुछ भी नहीं होता है, जो कि कंबल 'अपवाद' खंड को छोड़कर उस urllib3 अपवाद को पकड़ने में सक्षम नहीं होता है।
मैं ऐसा कर सकता हूं, लेकिन मैं वास्तव में उत्सुक हूं कि बिल्ली नमक क्या कर रहा है जिससे यह अपरिवर्तनीय हो। मैंने पाइथन के साथ काम करते समय इसे कभी नहीं देखा है, इसलिए मैं उत्सुक हूं कि यह कैसे हो रहा है और मैं इसके आसपास कैसे काम कर सकता हूं।
संपादित करें:
तो मैं अंत में इसे पकड़ने में सक्षम था।
import etcd
import urllib3.exceptions
from urllib3.exceptions import ReadTimeoutError
def test():
c = etcd.Client('127.0.0.1', 4001)
try:
c.read('/test1', wait=True, timeout=2)
except urllib3.exceptions.ReadTimeoutError:
return 'caught 1'
except urllib3.exceptions.HTTPError:
return 'caught 2'
except ReadTimeoutError:
return 'caught 3'
except etcd.EtcdConnectionFailed as ex:
return 'cant get away from me!'
except Exception as ex:
return 'HOW DID YOU GET HERE? {0}'.format(type(ex))
if __name__ == "__main__":
print test()
और जब रन:
[[email protected] _modules]# salt 'alpha' sjmh.test
alpha:
caught 3
हालांकि यह अभी भी मतलब नहीं है। अपवादों के बारे में मुझे क्या पता है, वापसी 'पकड़ा 1' होना चाहिए। पूर्ण वर्ग नाम का उपयोग करने के बजाय मुझे अपवाद का नाम सीधे आयात क्यों करना चाहिए?
अधिक संपादन!
तो, दो वर्गों के बीच तुलना जोड़ने से 'झूठी' उत्पन्न होती है - जो कि स्पष्ट है, क्योंकि छोड़कर खंड काम नहीं कर रहा था, इसलिए वे समान नहीं हो सकते थे।
मैंने c.read() को कॉल करने से ठीक पहले, स्क्रिप्ट में निम्नलिखित जोड़ा।
log.debug(urllib3.exceptions.ReadTimeoutError.__module__)
log.debug(ReadTimeoutError.__module__)
और अब मैं लॉग में इस मिल:
[DEBUG ] requests.packages.urllib3.exceptions
[DEBUG ] urllib3.exceptions
तो, कारण है कि जिस तरह से यह है पकड़े जाने प्रतीत होता है कि। यह सिर्फ etcd डाउनलोड करके भी प्रतिलिपि प्रस्तुत करने योग्य है और इस तरह पुस्तकालय और कुछ कर रही अनुरोध करता है:
#!/usr/bin/python
#import requests
import etcd
c = etcd.Client('127.0.0.1', 4001)
c.read("/blah", wait=True, timeout=2)
आप 'सही' अपवाद उठाया हो रही अंत होगा - etcd.EtcdConnectionFailed। हालांकि, 'अनुरोध' को अपूर्ण करें और आप urllib3.exceptions.ReadTimeoutError के साथ समाप्त हो जाएंगे, क्योंकि आदि अब अपवाद को पकड़ नहीं लेता है।
तो ऐसा प्रतीत होता है कि जब अनुरोध आयात किया जाता है, तो यह urllib3 अपवादों को फिर से लिखता है, और किसी अन्य मॉड्यूल को पकड़ने की कोशिश कर रहा है, विफल रहता है। साथ ही, ऐसा लगता है कि अनुरोधों के नए संस्करणों में यह समस्या नहीं है।
'" एचआरएम, यह अजीब है। आदि के पढ़ने को वापस भेजना चाहिए था। एडीसीडी कनेक्शन कनेक्शन "। वास्तव में अजीब नहीं है।'ReadTimeoutError' इस तथ्य का वर्णन करता है कि डेटा प्राप्त करने का समय अंडरलेइंग प्रोटोकॉल स्तर पर समाप्त हो गया है। 'कनेक्शनफेल्ड 'इस तथ्य का वर्णन करता है कि क्लाइंट दूरस्थ सेवा से कनेक्ट करने में असमर्थ था (कई कारणों से)। वे दो अलग-अलग स्थितियां हैं जिनका आप अनुभव कर रहे हैं, नेटवर्किंग में काफी आम हैं, खासकर यदि रिमोट सर्वर संसाधनों पर धीमा है और धीमा है। – Pynchia
पेंचिया, मैंने कहा कि इसे वापस लौटा देना चाहिए क्योंकि आम तौर पर, पाइथन-आदि 0.4.2 के साथ, जब टाइमआउट प्रतीक्षा प्रतीक्षा पर समाप्त हो जाता है, तो यह इत्यादि बढ़ाता है। एटीसीडीकनेक्शनफेल। यह एक स्थानीय आदि उदाहरण है और मैंने सत्यापित किया कि आदि था। साथ ही, जैसा कि अंतिम लिपि द्वारा प्रमाणित है, नेटवर्किंग के अलावा कुछ और चल रहा है। – sjmh
ओह हाँ। यह एक और कारण है कि कनेक्शन विफल हो सकता है। लेकिन आपके मामले में रीड टाइमआउट के कारण विफल हो रहा है। उस ने कहा, पुस्तकालय अजीब व्यवहार कर सकता है। – Pynchia