Catch "Could not open connection to gateway" in sshtunnel.py - python

Every now and then setting up a tunnel using sshtunnel.py fails because the gateway (ssh_host) complains the first time I connect to it. I would like to give it a few retries before giving up:
for attempt in range(5):
try:
forwarder.start()
except Exception, e:
print 'Error (trying again in five seconds):\n' + format(e.message))
time.sleep(5)
else:
break
else:
print 'Failed to setup a connection to the gateway'
sys.exit(1)
However, the error is not 'detected'. I took a peek in the sshtunnel.py code and found that the following code catches the related Paramiko exception:
except paramiko.ssh_exception.AuthenticationException:
self.logger.error('Could not open connection to gateway')
return
How do I catch this in my try:?

An SSHTunnel.py project member advised me to add forwarder._check_is_started() to my code:
for attempt in range(5):
try:
forwarder.start()
forwarder._check_is_started()
except BaseSSHTunnelForwarderError as e:
print 'Error (trying again in five seconds):\n' + format(e.message))
time.sleep(5)
else:
break
else:
print 'Failed to setup a connection to the gateway'
sys.exit(1)

Related

Cannot catch error, it is instead printed to the console

I am detecting whether the external IP has changed with miniupnpc. And during my testing I've noticed that when I turn off Wi-Fi (disconnect my pc from the internet) I get an error which I cannot catch with the exception.
It appears to be printed to the console.
u = miniupnpc.UPnP()
u.discoverdelay = config.svc_upnp_disc_delay
try:
discover = u.discover()
print(discover, 'device(s) detected')
if discover:
u.selectigd()
while True:
stat_info, stat_port, stat_error = u.statusinfo()
if stat_info == 'Connected':
if u.lanaddr != os.environ.get(config.envr_name_int_addr):
os.environ[config.envr_name_int_addr] = u.lanaddr
ext_ip = u.externalipaddress()
if ext_ip != os.environ.get(config.envr_name_ext_addr):
os.environ[config.envr_name_ext_addr] = ext_ip
print('+', end=' ', flush=True)
else:
print('-', end=' ', flush=True)
if stat_info != os.environ.get(config.envr_svc_status):
os.environ[config.envr_svc_status] = stat_info
time.sleep(5)
except Exception as e:
print('Exception :', e)
This is the error:
sendto: Network is unreachable
sendto: Network is unreachable
sendto: Network is unreachable
sendto: Network is unreachable
Is there any way I can catch this so I can log it in a log file instead of the console?
And what is causing it in the first place...because I am not printing it?
The fact that there are 4 errors being logged indicates that your try...except block might not work correctly.
Try using BaseException instead of Exception in your except clause.

How to properly use try/except in Python

I have a function that returns the DB connection handler from MongoDB. I have various other functions that makes a call to the DB, I figure let's throw the connection handler into a function so I don't have to define it in every function.
Does this look right? I guess my question is, if it can't make a connection to the DB server, it will print both messages Could not connect to server and No hosts found How can I go about only printing "Could not connect to the server."
def mongodb_conn():
try:
conn = pymongo.MongoClient()
except pymongo.errors.ConnectionFailure, e:
print "Could not connect to server: %s" % e
return conn
def get_hosts()
try:
conn = mongodb_conn()
mongodb = conn.dbname.collection
b = []
hosts_obj = mongodb.find({'_id': 'PR'})
for x in hosts_obj:
print x
except:
print "No hosts found"
get_hosts()
Move your conn = mongodb_conn() call out of the try .. except handler, and test if None was returned:
def get_hosts()
conn = mongodb_conn()
if conn is None:
# no connection, exit early
return
try:
mongodb = conn.dbname.collection
b = []
hosts_obj = mongodb.find({'_id': 'PR'})
for x in hosts_obj:
print x
except:
print "No hosts found"
You should, at all cost, avoid using a blanket except however; you are catching everything now, including memory errors and keyboard interrupts, see Why is "except: pass" a bad programming practice?
Use specific exceptions only; you can use one except statement to catch multiple exception types:
except (AttributeError, pymongo.errors.OperationFailure):
or you can use multiple except statements handle different exceptions in different ways.
Limit the exception handler to just those parts of the code where the exception can be thrown. The for x in hosts_obj: loop for example is probably not going to throw an AttributeError exception, so it should probably not be part of the try block.
Note that you'll need to adjust your mongodb_conn() function to not try and use the conn local if it has never been set; you'll get an UnboundLocal error if you do:
def mongodb_conn():
try:
return pymongo.MongoClient()
except pymongo.errors.ConnectionFailure, e:
print "Could not connect to server: %s" % e
Now the function returns the connection if successful, None if the connection failed.
You can also check if the server is available
like this:
from pymongo.errors import ConnectionFailure
client = MongoClient()
try:
# The ismaster command is cheap and does not require auth.
client.admin.command('ismaster')
except ConnectionFailure:
print("Server not available")

PYTHON - URLLIB2 Catch socket.error

Right now I am using urllib to pull some data off a server. However, the server is a bit dodgy and tends to go down every now and then for a minute or so. To deal with, when my code encounters an error, it just waits two seconds and tries again:
def fin(group):
try:
data = urllib2.urlopen("cool website" + group)
return data.read()
except urllib2.HTTPError, err:
time.sleep(2)
fin(group) #calls itself again
except urllib2.URLError, err:
time.sleep(2)
fin(group)
That works fine if the website goes down or I lose my internet connection. However, last night I left the code running and got this error:
socket.error: [Errno 10053] An established connection was aborted by the software in your host machine
I am not quite sure how to catch that. After some searching I am thinking I may need to do this:
except httplib.HTTPException, err:
time.sleep(2)
fin(group)
But I am not certain. Would anyone be able to help me out?

Create Socket Errors on Purpose / Python Script

I want to create socket errors (By doing things, obviously) but I've no idea how I should test if my script handles errors properly (If it dectes them.)
Currently, my code is this:
except socket.error as err:
print "Connection lost, waiting..."
time.sleep(5)
In theory, it should handle all the socket errors, print and then sleep (It's a part of a while loop.).
Any idea of how can I test it to see how it handles errors?
Use the raise statement:
try:
raise socket.error
except socket.error as err:
print "Connection lost, waiting..."
time.sleep(5)
Yet another example:
try:
raise AttributeError
except AttributeError:
print 'Sorry'
#Sorry
Also take a look at here and here

Retrying on Connection Reset

I'm using urllib.request to download files from the internet. However sometimes I get Connection Reset by Peer and I want to retry.
I tried the following, but it seems that e.errno contains socket error and not an actual errno:
while True:
try:
filename, headers = urllib.request.urlretrieve(url)
break
except IOError as e:
if e.errno != errno.ECONNRESET:
raise
except Exception as e:
raise
Any suggestions?
Well this part is not needed, first of all.
except Exception as e:
raise
And the arguments of the IOError is the type of error (socket error) and the error given to it. This error, in turn, is not the original error, but that error is in the args, so...
except IOError as e:
if e.args[1].args[0].errno != errno.ECONNRESET:
raise
Should work. I don't have a server that will reset on me, so I can't test it 100% But it works with ECONNREFUSED. :-)

Categories