4m1nh4j1
4m1nh4j1

Reputation: 4356

catch the exception of a subprocess called by another function

I would like to automate a script execution on a subprocess, so I am using subprocess lib to create the thread and schedule lib to schedule it.

I would like to verify that the script remotely executed, is working without problems. The code I was trying does not print any error when the script returns 1 (error) or when the script_file is absent. (And if I am not mistaken, adding the exception wrapper kills the subprocess and do its job )

import os
import sys
import subprocess
import multiprocessing
import schedule
import time
import functools

class MyClass:

        def catch_exceptions(job_func):
                @functools.wraps(job_func)
                def wrapper(*args, **kwargs):
                        try:
                                job_func(*args, **kwargs)
                        except:
                                import traceback
                                print ("Error")
                                print(traceback.format_exc())
                return wrapper


        @catch_exceptions
        def run(self, user, host, command):
                subprocess.call(["ssh", user + "@" + host, command])


        def sched(user, host, script_path):          
               schedule.every(0.01).minutes.do(self.run, user, host, script_path)

All suggestions are welcome, using wrappers is not the goal, but any solution to verify the execution of sched method is good also.

Upvotes: 0

Views: 2500

Answers (3)

Dunes
Dunes

Reputation: 40683

call returns the exit code of process. So you can check against that. Or try subprocess.check_call. It throws an exception when the process exits with a non-zero value, so you don't have to explicitly check the exit value, and catch the exception where you want to deal with it.

Examples:

exit_value = subprocess.call(cmd) 
if exit_value:
    ... 

or

try:
    subprocess.check_call(cmd) 
except CalledProcessError as e:
    ... 

Upvotes: 3

Niyojan
Niyojan

Reputation: 584

Use subprocess.Popen()

RunCmd = Popen( sCmd, shell=True, stdout=PIPE, stderr=PIPE)

for sLine in RunCmd.stdout:
            print( sLine.decode() )
            stdout.flush()
            aLog.append( sLine.decode() )
for sLine in RunCmd.stderr:
            print( sLine.decode() )
            stderr.flush()
            aErrorLog.append( sLine.decode() )
RunCmd.wait()
if RunCmd.returncode == 0:
            return RunCmd.wait()
        else: 
            return RunCmd.returncode

RunCmd.wait() will wait for the process to finish, and will return process code(for succuss or failure) This also prints the output at realtime.

Upvotes: -1

vks
vks

Reputation: 67968

x=subprocess.Popen(["ssh", user + "@" + host, command],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
output,error=x.communicate()
if error:
    print "there's an error!!!!!!!!!!!!!!:",error

You can try like this.subprocess.communicate returns output if successful or error if command fails.

Upvotes: 1

Related Questions