ETIMEOUT trying to catch error in usocket

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

ETIMEOUT trying to catch error in usocket

Post by davef » Sat May 29, 2021 8:56 am

According to the docs:
CPython raises a socket.timeout exception in case of timeout, which is an OSError subclass. MicroPython raises an OSError directly instead. If you use except OSError: to catch the exception, your code will work both in MicroPython and Cpython.
So, I tried this:

Code: Select all

try:
    addr = usocket.getaddrinfo(host, port)[0][-1]
except OSError as err:
    with open('errors.txt', 'a') as outfile:
        outfile.write('OSError is ' + err + '\n')
I often see Errno 116 ETIMEOUT in repl, but I don't see
anything in my errors.txt file.

How do I properly catch a ETIMEOUT error and allow my
program to ignore this error and keep working?

Thanks.
Last edited by davef on Sat May 29, 2021 9:35 am, edited 2 times in total.

johanson
Posts: 8
Joined: Sat May 22, 2021 1:04 pm

Re: ETIMEOUT trying to catch error in usocket

Post by johanson » Sat May 29, 2021 9:12 am

Check your indentation, the except OSError should be aligned with try, or remove the try/except block from within except block completely. Appending into the file should not be raising any OSError at all until things are seriously wrong.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ETIMEOUT trying to catch error in usocket

Post by davef » Sat May 29, 2021 9:34 am

Sorry copy/paste issue.

I previously had issues with saving stuff to /ramdisk/ so ended up trying to catch those as well. Edited to focus on the issue.

Thanks

johanson
Posts: 8
Joined: Sat May 22, 2021 1:04 pm

Re: ETIMEOUT trying to catch error in usocket

Post by johanson » Sat May 29, 2021 10:01 am

OSError does not have __str__ implemented so the implicit conversion to str fails and you get

Code: Select all

TypeError: can't convert 'OSError' object to str implicitly
. You can handle the exception based on the error code as follows:

Code: Select all

try:
    addr = usocket.getaddrinfo(host, port)[0][-1]
except OSError as err:
    if err.args[0] == -202:
        # no network available
        pass
    elif err.args[0] == 116:
        # socket.timeout
        pass
    ...

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ETIMEOUT trying to catch error in usocket

Post by davef » Sat May 29, 2021 10:09 am

OSError does not have __str__ implemented
Ouch, that is a new one for me.

I haven't seen TypeError, because I only get these errors maybe once a day and save them to a log. So, would miss them as I am not watching repl.

Thank you for the code example.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ETIMEOUT trying to catch error in usocket

Post by davef » Sat May 29, 2021 6:20 pm

The following has been running for the last 8 hours:

Code: Select all

        while True:
            counter +=1

            try:
                addr = usocket.getaddrinfo(host, port)[0][-1]
                counter = 0
                break
            except OSError as err:
                counter +=1
                if err.args[0] == -202:
                  # no network available
                    try:
                        with open('errors.txt', 'a') as outfile:
                            outfile.write('no network available' + '\n')
                    except OSError:
                        pass
                elif err.args[0] == 116:
                  # socket.timeout
                    try:
                        with open('errors.txt', 'a') as outfile:
                            outfile.write('socket timed-out' + '\n')
                    except OSError:
                        pass
and it logged 2 * no network available errors. I was surprised that it coped with the error and completed without having to use a continue after the try-except. This script can repeat 5 times then I bail-out.

Thanks again for helping me to sort this out.

MatthiasP
Posts: 7
Joined: Mon Apr 19, 2021 7:31 pm

Re: ETIMEOUT trying to catch error in usocket

Post by MatthiasP » Mon Jun 21, 2021 6:34 pm

Hi,

I have a similar problem. I would like to add proper exception handling to a non blocking socket write (and read) access:

Code: Select all

    def _sock_timeout(self, poller, socket_timeout):
        # omitting some details here...
        if self.sock:
            res = poller.poll([...])

    def _write(self, bytes_wr, length=-1):
        # omitting some details here...
        
        # check exception here:
        self._sock_timeout(self.poller_w, self.socket_timeout)
        
        # and check exception here:
        out = self.sock.write(bytes_wr, length)
I added some exception handling around _sock_timeout() and sock.write() above and found that (during my short testing period) the former never threw any exception, but sock.write() sometimes threw an exception with error codes -128 or -113.

Why do I get negative error codes? Decoding the error as suggested in https://docs.micropython.org/en/latest/ ... .errorcode - uerrno.errorcode[uerrno.exc] fails due to the negative array index. Following the cross references to CPython's errno did not help me any further.

The explanations in https://docs.micropython.org/en/latest/ ... ml#methods did not answer my questions, either.

Where can I look up all supported error codes (of a given MicroPython port) or - even better - all possible exceptions of any library call?

Thanks for any hints!

Cheers, Matthias

P.S.: Those exceptions don't seem to be critical - if I simply ignore them, the code works as expected.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ETIMEOUT trying to catch error in usocket

Post by davef » Mon Jun 21, 2021 8:04 pm

My understanding is that negative error codes are just the Micropython way of displaying what would be a Python error.

From http://mazack.org/unix/errno.php
Errno 113: No route to host
Errno 128: Key has been revoked, most of the Google hits are related to accessing Github

+1 for a list as I have spend many hours trying to capture errors.

Post Reply