Search code examples
pythonpython-3.xexceptiontraceback

Where error happened? exec(compile(script,"<string>",'exec'))


I have 2 files. In one of them the script (calling the function from another file) is compiled and executed. What I need is to identify where the error occurred: whether it was an error in creating a script (in which line of the script) in the user_script.py or it was error in the foo(parameter) function.

I want to catch any errors (SyntaxError, TypeError, etc) and handle them differently depending on whether it occurred in the script itself or in the function foo(parameter)

I show two examples with NameError but in principle I want to do the same with any type of errors. To which attributes should I refer to distinguish them?

Example 1

user_script.py

import sys
import traceback
from Catch_errors.my_function import function

script="a=1\nb=3\nfunction.foo(c)"
exec(compile(script,"<string>",'exec'))

my_function.py

class function:
    def foo(parameter):
        a = parameter
        print(a)  # or e.g. causing the error print(a+'sss')

Output:

Traceback (most recent call last):
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\pydevd.py", line 2199, in <module>
    globals = debugger.run(setup['file'], None, None)
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\pydevd.py", line 1638, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc) 
  File "C:/Users/Support/PycharmProjects/HelloWorldProject/Catch_errors/user_Script.py", line 7, in <module>
    exec(compile(script,"<string>",'exec'))
  File "<string>", line 3, in <module>
NameError: name 'c' is not defined

Example 2

user_script.py

import sys
import traceback
from Catch_errors.my_function import function

script="a=1\nb=3\nfunction.foo(2)"
exec(compile(script,"<string>",'exec'))

my_function.py

class function:
    def foo(parameter):
        a = parameter
        print(b)

Output:

Traceback (most recent call last):
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\pydevd.py", line 2199, in <module>
    globals = debugger.run(setup['file'], None, None)
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\pydevd.py", line 1638, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc) 
  File "C:/Users/Support/PycharmProjects/HelloWorldProject/Catch_errors/user_Script.py", line 5, in <module>
    script="a=1\nb=3\nfunction.foo("+b+")"
NameError: name 'b' is not defined

Solution

  • import sys, traceback
    from Catch_errors.my_function import function
    
    script = "a=1\nb=3\nfunction().foo(a)"
    
    try:
        compiled_script = compile(script,"<string>",'exec')
        exec(compiled_script)
    except:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        tr = traceback.extract_tb(sys.exc_info()[-1])
        print(tr)
        if "my_function.py" in tr[-1][0]:
            print("EXCEPTION IN FUNCTION "+str(tr[-1][-2])+"(), line '"+tr[-1][-1]+"'.")
            print(exc_obj.args[0])
        else:
            print('EXCEPTION IN USER SCRIPT: {}'.format(exc_obj))