-1

i am running a curl command to check the status of a website:

try:
    connectionTest = subprocess.Popen([r"curl --interface xx.xx.xx.xx http://www.yahoo.com"], shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    cstdout,cstderr = connectionTest.communicate()
    if cstdout:
        #print cstdout
        status = "OK"
    elif cstderr:
        #print cstderr
        status = "PROBLEM"
except:
    e = sys.exc_info()[1]
    print "Error: %s" % e

The code works fine except for the try:except statement as its not catching the exception properly, below is the output of the script when the interface is down, now i would like to catch that first line in the except statement... instead it being spawned...is this possible??

SIOCSIFFLAGS: Cannot assign requested address

PROBLEM
krisdigitx
  • 7,068
  • 20
  • 61
  • 97
  • 3
    Show us the whole stacktrace. What makes you think there is a problem? If your except clause is not being triggered, there is no exception. – Marcin Mar 26 '12 at 11:34
  • simply raise an exception if there is a problem in the output of the curl command. – Not_a_Golfer Mar 26 '12 at 11:38

3 Answers3

5

There is no exception thrown. You can check return code and throw an exception when it is not zero:

import sys, subprocess
try:
    connectionTest = subprocess.Popen([r"curl --interface 1.1.1.1 http://www.yahoo.com"], shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    cstdout,cstderr = connectionTest.communicate()
    if connectionTest.returncode:
        raise Exception("Curl returned %s"%connectionTest.returncode)
    if cstdout:
        #print cstdout
        status = "OK"
    elif cstderr:
        #print cstderr
        status = "PROBLEM"
except:
    e = sys.exc_info()[1]
    print "Error: %s" % e
Equidamoid
  • 1,447
  • 1
  • 13
  • 24
3

if any exception happens in subprocess, it will not be thrown. check stderr and raise appropriate exception

try:
    connectionTest = subprocess.Popen([r"curl --interface xx.xx.xx.xx http://www.yahoo.com"], shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    cstdout,cstderr = connectionTest.communicate()
    if cstdout:
        #print cstdout
        status = "OK"
    elif cstderr:
        #print cstderr
        status = "PROBLEM"
        raise some exception
except:
    e = sys.exc_info()[1]
    print "Error: %s" % e
pylover
  • 7,670
  • 8
  • 51
  • 73
0

Are you sure you need to call out to curl?

import urllib2
try:
    urllib2.urlopen("http://www.yahoo.com")
except urllib2.URLError as err:
    print(err)
except urllib2.HTTPError as err:
    print(err)

Secondly, it sounds like your interface address is dodgy, rather than your code. Check the --interface flag argument for correctness (ie: run the curl command outside of python and check that it works as expected.)

As a general point, you will never be able to catch a child process error inside of your python program (Which is what I think you are asking). You will have to rely on exit codes and stdout/err output, which is why a solution that relies on Python's included batteries will be much more robust.

If you need to specify the interface manually, you have several other options:

  1. PyCurl:

    import pycurl
    import StringIO
    c = pycurl.Curl()
    c.setopt(pycurl.URL, "http://www.python.org/")
    c.setopt(pycurl.CURLOPT_INTERFACE, "eth0")
    # [...]
    try:
        c.perform()
    except: # Handle errors here.
      pass 
    
  2. Change the source interface manually in python for urllib2
Community
  • 1
  • 1
brice
  • 24,329
  • 7
  • 79
  • 95