Catch OSErrors from Popen()s
authorW. Trevor King <wking@drexel.edu>
Thu, 13 Nov 2008 14:02:22 +0000 (09:02 -0500)
committerW. Trevor King <wking@drexel.edu>
Thu, 13 Nov 2008 14:02:22 +0000 (09:02 -0500)
From the subprocess module documentation:
http://www.python.org/doc/2.5.2/lib/node530.html

"The most common exception raised is OSError. This occurs, for example,
when trying to execute a non-existent file.  Applications should prepare
for OSError exceptions."

And from the os module documentation:
http://www.python.org/doc/2.5.2/lib/module-os.html

"exception error
    This exception is raised when a function returns a system-related
    error (not for illegal argument types or other incidental
    errors). This is also known as the built-in exception OSError. The
    accompanying value is a pair containing the numeric error code
    from errno and the corresponding string, as would be printed by
    the C function perror(). See the module errno, which contains
    names for the error codes defined by the underlying operating
    system.
    When exceptions are classes, this exception carries two
    attributes, errno and strerror. The first holds the value of the C
    errno variable, and the latter holds the corresponding error
    message from strerror(). For exceptions that involve a file system
    path (such as chdir() or unlink()), the exception instance will
    contain a third attribute, filename, which is the file name passed
    to the function."

I turned this up running be/test.py, when it defaulted to the tla client
which I didn't have installed.  I don't have things working yet, so I
can't create a bug at the moment...

libbe/arch.py
libbe/rcs.py

index 624aea3664e72e3ddbecafade236cf72980a8741..038325a1cbf5c50632c922aeec51904eae41490e 100644 (file)
@@ -24,7 +24,11 @@ if client is None:
     config.set_val("arch_client", client)
 
 def invoke(args):
-    q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+    try :
+        q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+    except OSError, e :
+        strerror = "%s\nwhile executing %s" % (e.args[1], args)
+        raise Exception("Command failed: %s" % strerror)
     output = q.stdout.read()
     error = q.stderr.read()
     status = q.wait()
index 77d6c9ad2111daf1593d95313e7a7dad29810eb0..4487fbae804733234129adb5f3865f65dc6ac140 100644 (file)
@@ -59,12 +59,16 @@ class CommandError(Exception):
         self.status = status
 
 def invoke(args, expect=(0,), cwd=None):
-    if sys.platform != "win32":
-        q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=cwd)
-    else:
-        # win32 don't have os.execvp() so have to run command in a shell
-        q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, 
-                  cwd=cwd)
+    try :
+        if sys.platform != "win32":
+            q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=cwd)
+        else:
+            # win32 don't have os.execvp() so have to run command in a shell
+            q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, 
+                      cwd=cwd)
+    except OSError, e :
+        strerror = "%s\nwhile executing %s" % (e.args[1], args)
+        raise CommandError(strerror, e.args[0])
     output, error = q.communicate()
     status = q.wait()
     if status not in expect: