0

I am trying to learn about exception handling in python by writing an International Space Station tracker in Python.

I have read https://docs.python.org/2/tutorial/errors.html and have found Handle errors with urllib2 useful, but I am struggling to understand how to have code continue to loop despite an exception being thrown and I'm not sure how to research this further.

I have this working code. It runs for days on my Raspberry Pi as part of a bigger program that makes a green light come on when ISS is overhead. Eventually though, an error is caused and the program halts. I'm looking for a way for the program to continue even if an error is called. I.e. This function is called every 10 seconds, but if there is an error I want the program to simply try again after 10 seconds while noting the error.

def issPosition(n):
    try:
        req = urllib2.Request("http://api.open-notify.org/iss-now.json")
        response = urllib2.urlopen(req)
        obj = json.loads(response.read())
        if n == "lat":
            return obj['iss_position']['latitude']
        elif n == "long":
            return obj['iss_position']['longitude']

    except urllib2.HTTPError, e:
        GPIO.output(24,True)
        time.sleep(0.1)
        GPIO.output(24,False)
        print 'HTTPError = ' + str(e.code)

    except urllib2.URLError, e:
        GPIO.output(26,True)
        time.sleep(0.1)
        GPIO.output(26,False)
        print 'URLError = ' + str(e.reason)

    except httplib.HTTPException, e:
        GPIO.output(26,True)
        time.sleep(0.1)
        GPIO.output(26,False)
        print 'HTTPException'

    except Exception:
        GPIO.output(26,True)
        time.sleep(0.1)
        GPIO.output(26,False)
        import traceback
        print 'generic exception: ' + traceback.format_exc() 

Pointers would be appreciated. Thank you.

Russell
  • 655
  • 2
  • 9
  • 21
  • sleep for ten seconds and log the error – Padraic Cunningham Jun 30 '15 at 20:42
  • what's the error that is not caught? – drolando Jun 30 '15 at 20:49
  • I would refractor your code so you Dont Repeat Yourself (__DRY__). Several lines are repeated and it will help to put it in a function so if you want to change sleep time, you change it in one place rather than 3. Also, you can still pass in e as an Exception in the last except block and cast e to a str. Finally, by handling the error, It will just continue. There is no other thing you need to do. There is a reason why its frowned upon to do try/except with out a specific error. – rady Jun 30 '15 at 20:49
  • I am not seeing any loop in your code . Are you calling issPosition from a loop? If yes , don't handle the exceptions in this method or simply re throw it. And let the loop handle the exception and continue the execution. – gipsy Jun 30 '15 at 20:51
  • are you using python 2 or 3? maybe you can use [this](https://docs.python.org/3/library/contextlib.html). search for suppress – CML Jun 30 '15 at 20:54
  • Also look into `logging` https://docs.python.org/2/library/logging.html. That will be able to write to a file rather than the console. – rady Jun 30 '15 at 21:26

1 Answers1

0

I am not seeing any loop in your code . Are you calling issPosition from a loop? If yes, don't handle exceptions in this method or re just re-throw it. And handle the exception in your loop and continue execution. For example:

while(True):
  try:
    result = issPosition(12334584)
    # Use your result here ....
  except:
    # Log and continue
    continue

** This will run for ever. You may want to add extra logic to end the loop eventually.

gipsy
  • 3,859
  • 1
  • 13
  • 21
  • Why has this been down voted? Exploring "continue" seems like a good step? – Russell Jun 30 '15 at 21:05
  • @Russell Probably because it bad practice to do a try:/except: like that. Generally, you want to catch only errors you can handle. What happens if you are iterating over a NoneType and that causes issues later on the program where it destroys something else? Normally that will raise a NoneType Error, but this way it does nothing. Also how do you quit this? You can't do an keyboard interrupt, the except will catch that. You could add extra logic to end the loop but that'll be a pain. – rady Jun 30 '15 at 21:20
  • My answer was to give op an idea to solve the problem. Any solution will involve something similar you may choose to handle exception selectively. And above all if the requirement is to run for ever, we have to just do that. Everything else is just talk. – gipsy Jun 30 '15 at 21:29
  • 1
    @gipsy Or you can set it to run as a deamon (Which is the proper way of doing this kind of stuff) or even a cron script (which will run every 1 minute at the earliest.) – rady Jun 30 '15 at 21:43
  • Just genuinely curious. What will happen to the deamon on exception? Don't you need the similar continue semantic in ur deamon as well? . But you made me thinking and I think the best solution for his raspberry py app is to run it from cron every minute or so. – gipsy Jun 30 '15 at 21:55
  • @gipsy kind of yea. but the thing with deamons is that you register to listen for signals and on those signals you do some action (like exit). This allows you to run some clean up code on exit and control the program at the same time. the way you have the code above (as is) would require you to stop it using kill -9 which will just kill without cleaning up anything. – rady Jun 30 '15 at 23:01
  • @rady no question about having a hook for exiting the loops. I believe I was clear on that. For the original question of continuing in a loop even when there is an exception, I am still stand by my answer. It is up to Op to see if that was helpful in resolving his problem. – gipsy Jun 30 '15 at 23:27
  • @gipsy Thanks for your input. Answer chosen because it lead to the solution. The function was not in a loop, but was called from within a loop so when an error was caused it terminated the program. Learning about "Continue" has helped a lot. – Russell Jul 01 '15 at 20:49
  • @rady Thanks for your comments. I have avoided the deamon option as the function is called every 10 seconds (some times the ISS passes over for a very short time so I wanted to catch it accurately). – Russell Jul 01 '15 at 20:50