1

I would like to write a python code that run several functions sequentially. Actually, start from first function and check if it doesn't throw any error, then start running second function and so on. I used following strategy, but it didn't stop when first function throws error and keep running other function:

    try:
        firstFunc()
    except:
        raise ExceptionFirst('job failed!')
    else:
        try:
            secondFunc()
        except:
            raise ExceptionSecond('second function failed!')

------------------------------ ADD-ON-------------------------------------------

All functions defined in a separate way and don't have connection with each other. The structure of each function is like following (e.g., first fucntion):

p = subprocess.Popen("abaqus script=py.py", shell=True)
p.communicate() #now wait
if p.returncode == 0:
    print("job is successfully done!")

I changed my function as follows and it worked successfully:

p = subprocess.check_call("abaqus script=py.py", shell=True)
if p == 0:
    print("job is successfully done!")

But, I stuck with the same problem for one of my functions which has following structure:

p = subprocess.check_call("java -jar javaCode.jar XMLfile.xml", shell=True)
if p == 0:
    print("job is successfully done!")

It throws an error, but the python print out "job is successfully done!" for that and keeps running other functions!!

---------------------------------------- Full Code ------------------------------------------------

import subprocess
import sys, os

def abq_script():
    p = subprocess.check_call("abaqus script=py.py", shell=True)
    if p == 0:
        print("job is successfully done!\n")

def abq_java():
    p = subprocess.check_call("java -jar FisrtJavaCode.jar", shell=True)
    if p == 0:
        print("job is successfully done!\n")

def java_job():
    p = subprocess.check_call("java -jar secondJavaCode.jar XMLfile.xml", shell=True)
    if p == 0:
        print("job is successfully done!\n")

def abq_python_java():  
    funcs = [abq_script, abq_java, java_job]
    exc = Exception('job failed!')
    for func in funcs:
        try:
            func()
        except Exception as e:
            print(str(e))
            break

If the first or second function shows an error, the exception throws an exception and program stops from running. But, if last function (java_job) shows an error, program doesn't throw any exception and keeps running.

7
  • @KasraAD what if statement.......? Commented Feb 17, 2015 at 16:41
  • I meant from "check if it doesn't throw any error" was the exception part. Commented Feb 17, 2015 at 16:56
  • This one won't throw any exceptions. If you use subprocess.check_call, it will check the return code for you and raise a CalledProcessError exception if it's nonzero. Commented Feb 17, 2015 at 18:01
  • @babbageclunk You mean using "p = subprocess.check_call()" instead of "p = subprocess.Popen()"? Commented Feb 17, 2015 at 18:26
  • @babbageclunk I've got your point, but in some cases your solution seems not working. I explained at the end of my question. Commented Feb 17, 2015 at 20:19

2 Answers 2

4

Put your functions into a list and iterate through them, calling each.

funcs = [firstFunc, secondFunc, ...]
for func in funcs:
    try:
        func()
    except ValueError: # Or whatever specific exception you want to handle...
        # Handle it...
        break

(See here for discussion of why it's far better to catch the specific exception you're trying to handle.)

Edit:

If each function has a specific set of exceptions that you'd like to catch, but it differs for the functions, you could put them into the list with the functions.

funcs = [
    (firstFunc, (ValueError, TypeError)),
    (secondFunc, (ZeroDivisionError, NameError)),
    # More function and their exceptions here...
]
for func, exceptions_to_catch in funcs:
    try:
        func()
    except exceptions_to_catch: 
        # Handle it...
        break

More edit:

I'd structure this differently - the only thing that differs between jobs is the command to run. You could do this with something like:

commands = [
    "abaqus script=py.py",
    "java -jar FisrtJavaCode.jar",
    "java -jar javaCode.jar XMLfile.xml",
]
for command in commands:
    subprocess.check_call(command, shell=True)
    print 'command {!r} successfully done!'.format(command)    

You don't need to catch the subprocess.CalledProcessError that might be thrown if one of the commands sets a nonzero return code - that'll stop processing the way you want.

Now it sounds like the underlying problem is that java -jar javaCode.jar XMLfile.xml doesn't set the return code correctly when it fails.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your comment. I tried your solution, but it didn't break after first function throws an error.The problem is remains on exception type. It's not a fixed exception type and may vary with different input files or different functions.
Well, if you're genuinely in the situation that you can't control what kind of exception the functions you're calling will throw, get rid of the ValueError in the except clause.
Even in that case, you should catch except Exception so you don't end up catching a KeyboardInterrupt or etc
Also, each function may raise different exception in which I don't know all of them, because of this I used "raise exception".
@babbageclunk thank you very much for helping me, your last solution was very helpful. But, I still have problem with the last command, I don't know why? Another question, How can I manage some calculations between two commands, for example the last command may need some info (like some parameter calculation)?
|
1

Why are you trying to try/except if you're only throwing another exception? Let the original exception bubble up if you're trying to stop execution thereafter.

firstFunc()
secondFunc()
thirdFunc()
we_all_about_the_funk()

8 Comments

what do you mean "Let the original exception bubble up ..."?
If you can't handle an exception at the time, don't catch it. Let the calling scope catch it instead.
I still have the same problem with using your solution. My second function throws an error, but the python keep running third function and so on.
@SiamakMalek You'll have to give us more information on how you're running the functions then, because when Python sees an uncaught exception it stops. My guess is that you have firstFunc calling secondFunc and etc from an earlier attempt to chain your function calls.
From this description, @AdamSmith's solution is the best. If one of the functions throw an exception, execution will stop.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.