Page 1 of 2
How can I trap socket errors?
Posted: Tue Nov 22, 2016 2:55 am
by NTL2009
With help from this forum and the docs, I've come a long way in getting my little application running. So now I'm getting into the nitty-gritty of handling unexpected events, outside of my rigged test conditions.
I use the code I found here to create a socket to send/receive from a server I have running on another computer on my local network.
Code: Select all
s = socket.socket()
time.sleep(0.1)
s.connect((host, port))
That code works fine, but of course I get an error if the server isn't running when I try to access it. How can I test for this and handle it 'gracefully'? In my case, I would just skip and try again an hour later, my data is stored in a file until I connect and upload it, so it's fine for me to just continue with my other operations until the socket connection is made.
I saw this socket.error statement in the docs: (
http://docs.micropython.org/en/latest/w ... ocket.html)
Exceptions --- socket.error --- socket.timeout
But I don't know how to use these in my code. Can anyone provide an example for me? I saw examples of a 'try:' and 'except socket.error, (value,message):' command, but couldn't seem to get that to work, got syntax errors at the 'except' line, and was wondering if maybe this is not yet fully implemented in MicroPython (ESP8266), or most likely a coding error on my part? I'm new to this, so examples really help.
Or some alternate to just ignore this and allow the code to return from the function?
TIA
Re: How can I trap socket errors?
Posted: Tue Nov 22, 2016 6:54 am
by Roberthh
This piece of code does in principle what you seem to ask for;
Code: Select all
import time
import socket
s = socket.socket()
time.sleep(0.1)
try:
s.connect(("1.2.3.4", 1234))
except Exception as err:
print("Exception", err)
try/execpt is implemented in MicroPython, but maybe not all exception values. The link in your post points at the WiPy port, which is somewhat different to the ESP8266 port.
Re: How can I trap socket errors?
Posted: Tue Nov 22, 2016 7:11 am
by pythoncoder
@NTL2009 I would study the output from your code example to see what exception is thrown. For example
Code: Select all
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>>
In that instance the exception is ZeroDivisionError. If you wanted to trap that, you would write
Code: Select all
try:
code_which_might_fail()
except ZeroDivisionError:
do_something_about_it()
>>>
In general it's bad practice to write
except Exception because that will trap all errors including (for example) syntax errors in your code. It's best to trap and deal with specific exceptions.
Re: How can I trap socket errors?
Posted: Tue Nov 22, 2016 12:47 pm
by jms
Generally socket calls throw OSErrors or something derived from them.
As said don't catch everything or it'll include KeyboardInterrupts as well and that'll get annoying.
The other mistake is to catch exceptions and carry on silently as if everything is ok.
Jon
Re: How can I trap socket errors?
Posted: Tue Nov 22, 2016 2:42 pm
by NTL2009
Thanks so much! I will try these later today and report back.
Looks like the key is to use the "except Exception as err:" instead of my attempt with " except socket.error".
Fortunately, the way I have my app arranged, I store the events I'm monitoring in a file (ON/OFF changes in state of an appliance like a well pump, sump pump, freezer, etc), and attempt an upload each hour during the day when my computer would be on..
So if the socket isn't available, I'll just skip it until the next hour, the code is already set to handle that, I just needed a way to handle the no-connect state w/o crashing.
More later.....
Re: How can I trap socket errors?
Posted: Wed Nov 23, 2016 3:24 am
by NTL2009
OK, got a chance to add the above code sample into my code (within a function), and all works as I wanted.
Code: Select all
s = socket.socket()
time.sleep(0.1)
try:
s.connect((host, port))
except Exception as err:
print("Exception", err)
return
# continue if connected
And this is the err if no server is running:
[Errno 104] ECONNRESET
Thanks - now on to tackling future memory errors. It runs fine, and I call gc.collect ever time I loop to make another check on GPIO status, and have ~ 15000 free, but it seems if I add another function it won't even load to run, just errors before running ( I assume it runs out of RAM as it tries to analyze the code). But I have more studying/experimenting to do, and will start a new thread if I have more questions.
Pretty amazing what this little board an Micropython can do!
Re: How can I trap socket errors?
Posted: Wed Nov 23, 2016 7:18 am
by Roberthh
Hello @NTL2009,
like @jms and @pythoncoder told, it is not allways good to have an exception which catches everything, like my example. Normally the exception should be specific for the error you expect. If you do not know that beforehand, you should at least exclude keyboard interrupt, by adding a specific exception for it like:
Code: Select all
except KeyboardInterrupt:
raise # stop in case of Ctrl.C
except Exception as err:
# handling everything else
Re: How can I trap socket errors?
Posted: Wed Nov 23, 2016 12:03 pm
by deshipu
"KeyboardInterrupt" is just one example of an exception you don't want to catch (another is MemoryError), but it's fine to do "except Exception:", because neither "KeyboardInterrupt", nor other such exceptions are not included in "Exception". That also means you don't need to catch and re-raise them explicitly.
Re: How can I trap socket errors?
Posted: Wed Nov 23, 2016 7:08 pm
by ernitron
I actually use:
Code: Select all
socket = socket.socket()
socket.settimeout(0.5) # otherwise it will wait forever
socket.listen(1) # maximum number of queued connections
while True:
try:
conn, addr = self.socket.accept()
except KeyboardInterrupt:
return
except: # Timeout
do_something_with_timeout_exception()
continue
try:
req = conn.readline()
except: # Timeout
conn.close()
return
This is because you can timeout on any socket operation.
EDITED there exist except socket.timeout
Re: How can I trap socket errors?
Posted: Wed Nov 23, 2016 8:46 pm
by Roberthh
There seem to be no socket.timeout in the ESP8266 port.