user1978912
user1978912

Reputation: 47

subprocess error handling slipping through

I have been stuck on this a little while. Basically I have followed a number of subprocess usage examples, but I guess I must have some other issue.

I am writing a script that runs through a dir of movie files and runs exiftool on each of them to pull out some info about them.

I can make it work, until I strike a condition where exiftool errors. Such as Error: File format error ... so I am trying to catch that or any error that exiftool generates (even the error message could be handy to have as a variable), and just skip over that file.

In the below code, myArg is just the path to the file.

try:
    proc = subprocess.Popen(["exiftool", "-s", "-ImageWidth", "-ImageHeight", "-VideoFrameRate", "-CompressorName", "-MediaDuration", myArg], stdout=subprocess.PIPE)
    (out, err) = proc.communicate()
except OSError:
    print "Pass, something is borked..."
    pass

Upvotes: 0

Views: 2266

Answers (3)

ali_m
ali_m

Reputation: 74252

There are lots of ways to do this. You could use subprocess.call if you just want the return code:

import subprocess

ret = subprocess.call(['ls', 'sadknlsknfd'])
if ret:
    print('Something is borked\nreturncode:%i' % ret)

# Something is borked
# returncode:2

Or subprocess.check_call to raise an exception:

try:
    subprocess.check_call(['ls', 'sadknlsknfd'])
except subprocess.CalledProcessError as e:
    print('Something is borked\ncommand: %s\noutput: %s\nreturncode:%i'
          % (e.cmd, e.output, e.returncode))

# Something is borked
# command: ['ls', 'sadknlsknfd']
# output: None
# returncode:2

Or if you want the output as well you could use subprocess.check_output:

try:
    # note that `out` will be undefined if the call fails
    out = subprocess.check_output(['ls', 'sadknlsknfd'])
except subprocess.CalledProcessError as e:
    print('Something is borked\ncommand: %s\noutput: %s\nreturncode:%i'
          % (e.cmd, e.output, e.returncode))

# Something is borked
# command: ['ls', 'sadknlsknfd']
# output: 
# returncode:2

To get the STDERR message as well, you can redirect it to STDOUT:

try:
    out = subprocess.check_output(['ls', 'sadknlsknfd'], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
    # `out` will be undefined if the call fails
    print('Something is borked\ncommand: %s\noutput: %s\nreturncode:%i'
          % (e.cmd, e.output, e.returncode))

# Something is borked
# command: ['ls', 'sadknlsknfd']
# output: ls: cannot access sadknlsknfd: No such file or directory

# returncode:2

You could also use subprocess.Popen.communicate like this:

p = subprocess.Popen(['ls', 'saddsfsdf'],
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = p.communicate()
ret = p.returncode
if ret:
    print('Something is borked\nstdout:%s\nstderr:%s\nretcode:%i'
          % (out, err, ret))

# Something is borked
# stdout:
# stderr:ls: cannot access saddsfsdf: No such file or directory

# retcode:2

Upvotes: 2

foz
foz

Reputation: 3379

I think what you're looking for is to get the exit code from exiftool. It should return 0 on success, so to check for an error you can add this after your proc.communicate():

if proc.returncode != 0:
    print "Pass, something is borked..."

If the error message went to stdout, you should have it in your out variable. If it goes to stderr, add stderr=subprocess.PIPE to your pOpen command and then it should be in err.

Upvotes: 1

nagato
nagato

Reputation: 93

If I understood correctly you want to pass for any error that can occurred while reading file,if so then generalised error handling,instead of OsError

except Exception as e:
   print "Error Descr"+ str(e)
   pass

Upvotes: 0

Related Questions