Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details
If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.
If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.
Will an error in a Python Script Action stop a Macro?
- caffeinatedcoder
- Posts: 20
- Joined: Wed Jul 06, 2016 4:56 pm
Will an error in a Python Script Action stop a Macro?
Does anyone know if I have a Python Script in the middle of a macro and there is an Unhandled error within the Python Script will it stop the Macro from continuing or will the actions after the Python Script action still run?
pro┬Àgram┬Àmer (n) An organism capable of converting caffeine into code.
- kgschlosser
- Site Admin
- Posts: 5190
- Joined: Fri Jun 05, 2015 5:43 am
- Location: Rocky Mountains, Colorado USA
Re: Will an error in a Python Script Action stop a Macro?
good question. i believe it will. but i could be wrong. never really thought about it. but with how the code for a macro is run in the same thread i believe it will.. but it will also cause that thread to terminate causing more then just the macro to stop running. because the macro is not run in a thread of it's own. (again this is all an I think. I would have to look at the code)
- caffeinatedcoder
- Posts: 20
- Joined: Wed Jul 06, 2016 4:56 pm
Re: Will an error in a Python Script Action stop a Macro?
Thanks for the quick reply! I would very much like to know for sure. And if that's the case I wish there were a way to allow the macro to continue even after an error within the Python Script action. For some reason I feel like I read somewhere that Python Script actions are executed within their own thread and not the Macros, but I could also be wrong.
Below is the code I have in the Python Script action
I was hoping to avoid having to wrap every single action in it's own error handler (to report which specific command fails, should any of them fail) and just be able to see which line of the Python Script the error occurred by looking at the EG log, then rest easy knowing the rest of my macro also ran. Do you have any advice how I should go about the situation? Is there anyway to allow this sort of behavior to allow errors to be ignored (but still logged in EG)?
Below is the code I have in the Python Script action
Code: Select all
import shutil
import os
import stat
def remove_readonly(func, path, excinfo):
os.chmod(path, stat.S_IWRITE)
func(path)
#os.chmod is used to turn off Read-Only attribute
os.chmod("Q:/Setup.vbs", stat.S_IWRITE)
#os.remove is used to remove individual files
os.remove("Q:/Setup.vbs")
#shutil.rmtree is used to remove entire directories
#remove traces of file
shutil.rmtree("Q:/My Resources", onerror=remove_readonly)
shutil.rmtree("Q:/Me", onerror=remove_readonly)
shutil.rmtree("C:/Documents/Project Development", onerror=remove_readonly)pro┬Àgram┬Àmer (n) An organism capable of converting caffeine into code.
Re: Will an error in a Python Script Action stop a Macro?
For a simple test put somewhere in your (working) script a and see what happens.
Code: Select all
raise ValueError- caffeinatedcoder
- Posts: 20
- Joined: Wed Jul 06, 2016 4:56 pm
Re: Will an error in a Python Script Action stop a Macro?
This is the result when adding the line you suggested. The OSD action did run, so I guess that means that the macro does continue to run, right? How could I incorporate that into my actual script posted in my earlier comment?


pro┬Àgram┬Àmer (n) An organism capable of converting caffeine into code.
Re: Will an error in a Python Script Action stop a Macro?
Yes, looks like the macro continues(, but not the script). What do you mean with "incorporate that into my actual script"?
- caffeinatedcoder
- Posts: 20
- Joined: Wed Jul 06, 2016 4:56 pm
Re: Will an error in a Python Script Action stop a Macro?
Is there a way for me to use the `raise ValueError` in my script so that the error that occurs in the Python Script action is logged in the EG log while the rest of the Python Script action also tries to continue? I want to be able to know if any of the commands in the python script cause an error, but I want the rest of the script to run through to perform as many of the actions in the python script that it can. Is that possible? I'm not quite sure how to set that up in python. Doesn't it have something to do with
I don't know how to make my python script continue if there is an error.
So, to summarize, I'm trying to:
Code: Select all
try:
except:
finally:So, to summarize, I'm trying to:
- Have the Python Script try every single command in it, continuing onto all the commands below any command that causes an error while logging the error in EG Log
- Have the Macro continue after the Python Script errors (which I believe we've already figured out that it will)
pro┬Àgram┬Àmer (n) An organism capable of converting caffeine into code.
Re: Will an error in a Python Script Action stop a Macro?
Ah, ok. I think thats not possible inside a python script action. Because in the moment the exception is shown in the log, the script is already stopped (only the [python] script [action], not the whole macro where the python script action belongs to). So you would need to use try/except.
- caffeinatedcoder
- Posts: 20
- Joined: Wed Jul 06, 2016 4:56 pm
Re: Will an error in a Python Script Action stop a Macro?
Okay, so I've taken some time to tweak my Python Script action to the following.
First Python Script Action:
Then once that's down, two actions later I check to see if the paths were successfully removed with the following
Second Python Script Action:
Will this work? I'm not familiar with all the mechanics of python functions, so I don't know if I'm able to use a `shutil.rmtree` command that has an `onerror` function defined within a try/except block and have the try/except block's except run. But, looking at the documentation (source: https://docs.python.org/dev/library/shutil.html) for the `shutil.rmtree` command it states
First Python Script Action:
Code: Select all
import shutil
import os
import stat
def remove_readonly(func, path, excinfo):
os.chmod(path, stat.S_IWRITE)
func(path)
try:
#os.chmod is used to turn off Read-Only attribute
os.chmod("Q:/-----.vbs", stat.S_IWRITE)
#os.remove is used to remove individual files
os.remove("Q:/-----.vbs")
except:
pass
#shutil.rmtree is used to remove entire directories
#remove traces of file
try:
shutil.rmtree("Q:/FolderToRemove1", onerror=remove_readonly)
except:
pass
try:
shutil.rmtree("Q:/FolderToRemove2", onerror=remove_readonly)
except:
pass
try:
shutil.rmtree("Q:/FolderToRemove3", onerror=remove_readonly)
except:
pass
try:
shutil.rmtree("Q:/FolderToRemove4", onerror=remove_readonly)
except:
pass
try:
shutil.rmtree("Q:/FolderToRemove5", onerror=remove_readonly)
except:
pass
try:
shutil.rmtree("C:/Users/mhill/Desktop/screenshots", onerror=remove_readonly)
except:
passSecond Python Script Action:
Code: Select all
import os
#Test if directories still exists
eg.globals.PDEVdirectory = os.path.exists("C:/DeletedDirectory1")
eg.globals.PubESPAdirectory = os.path.exists("Q:/DeletedDirectory2")
eg.globals.PubASIRdirectory = os.path.exists("Q:/DeletedDirectory3")
eg.globals.DWNLDSdirectory = os.path.exists("C:/DeletedDirectory4")
eg.globals.DOCSdirectory = os.path.exists("C:/DeletedDirectory5")
eg.globals.SCRNSHTSdirectory = os.path.exists("C:/DeletedDirectory6")
#Print results to log
if not eg.globals.PDEVdirectory:
print 'PDEV directory successfully scrubbed'
else:
print 'PDEV directory scrub failed'
if not eg.globals.PubESPAdirectory:
print 'PubESPA directory successfully scrubbed'
else:
print 'PubESPA directory scrub failed'
if not eg.globals.PubASIRdirectory:
print 'PubASIR directory successfully scrubbed'
else:
print 'PubASIR directory scrub failed'
if not eg.globals.DWNLDSdirectory:
print 'DWNLDS directory successfully scrubbed'
else:
print 'DWNLDS directory scrub failed'
if not eg.globals.DOCSdirectory:
print 'DOCS directory successfully scrubbed'
else:
print 'DOCS directory scrub failed'
if not eg.globals.SCRNSHTSdirectory:
print 'SCRNSHTS directory successfully scrubbed'
else:
print 'SCRNSHTS directory scrub failed'Correct me if I'm wrong, but this to me sounds like the `onerror` function will run once if a `shutil.rmtree` command errors, then when the command is trying to re-run after its `onerror` function runs it will raise the error once again, this time not triggering the `onerror` function. So, would the error trigger its corresponding `except` block then? That's what I took it as, which is why I tweaked the code as I did above. Can anyone confirm that this is how the programmatic flow will work? Also, can anyone confirm that the above code will work for what I'm trying to accomplish?...to remove a directory tree on Windows where some of the files have their read-only bit set. It uses the onerror callback to clear the readonly bit and reattempt the remove. Any subsequent failure will propagate.
pro┬Àgram┬Àmer (n) An organism capable of converting caffeine into code.
- kgschlosser
- Site Admin
- Posts: 5190
- Joined: Fri Jun 05, 2015 5:43 am
- Location: Rocky Mountains, Colorado USA
Re: Will an error in a Python Script Action stop a Macro?
sure there is a way...
with EG there is always a way!!!
ok so you will do this at each point where you think there could be a potential error.
i am going to give you an example code here
this is pseudo code and i have not run it at all.
but this shows what exception catching is or what is known as "duck typing"
it's easier to ask forgiveness for doing something and it's wrong then it is to ask for permission.. LOL
but when an exception is raised for doing something wrong you can "catch" it with try, except
now there are many different error types
StopIteration - Raised when the next() method of an iterator does not point to any object.
SystemExit - Raised by the sys.exit() function.
StandardError - Base class for all built-in exceptions except StopIteration and SystemExit.
ArithmeticError - Base class for all errors that occur for numeric calculation.
OverflowError - Raised when a calculation exceeds maximum limit for a numeric type.
FloatingPointError - Raised when a floating point calculation fails.
ZeroDivisonError - Raised when division or modulo by zero takes place for all numeric types.
AssertionError - Raised in case of failure of the Assert statement.
AttributeError - Raised in case of failure of attribute reference or assignment.
EOFError - Raised when there is no input from either the raw_input() or input() function and the end of file is reached.
ImportError - Raised when an import statement fails.
KeyboardInterrupt - Raised when the user interrupts program execution, usually by pressing Ctrl+c.
LookupError - Base class for all lookup errors.
IndexError - Raised when an index is not found in a sequence.
KeyError - Raised when the specified key is not found in the dictionary.
NameError - Raised when an identifier is not found in the local or global namespace.
UnboundLocalError - Raised when trying to access a local variable in a function or method but no value has been assigned to it.
EnvironmentError - Base class for all exceptions that occur outside the Python environment.
IOError - Raised when an input/ output operation fails, such as the print statement or the open() function when trying to open a file that does not exist. and also Raised for operating system-related errors.
SyntaxError - Raised when there is an error in Python syntax.
IndentationError - Raised when indentation is not specified properly.
SystemError - Raised when the interpreter finds an internal problem, but when this error is encountered the Python interpreter does not exit.
SystemExit - Raised when Python interpreter is quit by using the sys.exit() function. If not handled in the code, causes the interpreter to exit. and Raised when Python interpreter is quit by using the sys.exit() function. If not handled in the code, causes the interpreter to exit. and Raised when an operation or function is attempted that is invalid for the specified data type.
ValueError - Raised when the built-in function for a data type has the valid type of arguments, but the arguments have invalid values specified.
RuntimeError - Raised when a generated error does not fall into any category.
NotImplementedError - Raised when an abstract method that needs to be implemented in an inherited class is not actually implemented.
now you do not have to specify an exceptionand can just do
but this is really not good form and it will catch all exceptions, even ones you may not want it to.
you can also group the exceptions together
and if my chance you want to catch the exception and do some code and then raise the exception
or if you want to run it way later on down the line
and exception handling can be used in just about everywhere in python code
this is nice because if someone doesn't have a specific library, it doesn't halt the code.
if you have any questions fire away
with EG there is always a way!!!
ok so you will do this at each point where you think there could be a potential error.
i am going to give you an example code here
Code: Select all
import traceback
test_a = [1, 2, 4, 5, 6, 7]
test_b = [1, 2, 3]
testdict = {}
try:
if test_a[0] == 1 and test_b[3] == 4:
try:
if test_a[20] == 5:
test = None
except IndexError:
traceback.print_exc()
except IndexError:
traceback.print_exc()
try:
print textDict['test']
except KeyError:
traceback.print_exc()
but this shows what exception catching is or what is known as "duck typing"
it's easier to ask forgiveness for doing something and it's wrong then it is to ask for permission.. LOL
but when an exception is raised for doing something wrong you can "catch" it with try, except
now there are many different error types
StopIteration - Raised when the next() method of an iterator does not point to any object.
SystemExit - Raised by the sys.exit() function.
StandardError - Base class for all built-in exceptions except StopIteration and SystemExit.
ArithmeticError - Base class for all errors that occur for numeric calculation.
OverflowError - Raised when a calculation exceeds maximum limit for a numeric type.
FloatingPointError - Raised when a floating point calculation fails.
ZeroDivisonError - Raised when division or modulo by zero takes place for all numeric types.
AssertionError - Raised in case of failure of the Assert statement.
AttributeError - Raised in case of failure of attribute reference or assignment.
EOFError - Raised when there is no input from either the raw_input() or input() function and the end of file is reached.
ImportError - Raised when an import statement fails.
KeyboardInterrupt - Raised when the user interrupts program execution, usually by pressing Ctrl+c.
LookupError - Base class for all lookup errors.
IndexError - Raised when an index is not found in a sequence.
KeyError - Raised when the specified key is not found in the dictionary.
NameError - Raised when an identifier is not found in the local or global namespace.
UnboundLocalError - Raised when trying to access a local variable in a function or method but no value has been assigned to it.
EnvironmentError - Base class for all exceptions that occur outside the Python environment.
IOError - Raised when an input/ output operation fails, such as the print statement or the open() function when trying to open a file that does not exist. and also Raised for operating system-related errors.
SyntaxError - Raised when there is an error in Python syntax.
IndentationError - Raised when indentation is not specified properly.
SystemError - Raised when the interpreter finds an internal problem, but when this error is encountered the Python interpreter does not exit.
SystemExit - Raised when Python interpreter is quit by using the sys.exit() function. If not handled in the code, causes the interpreter to exit. and Raised when Python interpreter is quit by using the sys.exit() function. If not handled in the code, causes the interpreter to exit. and Raised when an operation or function is attempted that is invalid for the specified data type.
ValueError - Raised when the built-in function for a data type has the valid type of arguments, but the arguments have invalid values specified.
RuntimeError - Raised when a generated error does not fall into any category.
NotImplementedError - Raised when an abstract method that needs to be implemented in an inherited class is not actually implemented.
now you do not have to specify an exceptionand can just do
Code: Select all
try:
except:
you can also group the exceptions together
Code: Select all
try:
except (KeyError, IndexError, ValueError):
Code: Select all
try:
except KeyError:
# do some code here then raise the same exception
raise
Code: Select all
try:
test = boo[1]
err = None
except KeyError as err:
test = none
if err:
raise err
Code: Select all
try:
import test_import
do some code here....
except ImportError:
do different code here
if you have any questions fire away
- kgschlosser
- Site Admin
- Posts: 5190
- Joined: Fri Jun 05, 2015 5:43 am
- Location: Rocky Mountains, Colorado USA
Re: Will an error in a Python Script Action stop a Macro?
and i do have a question for you i notice you are putting all the os.path queries into globals. are the globals used elsewhere in your tree??? some other script??
because if not it doesn't have to be eg.globals.VARNAME it can be just VARNAME
because if not it doesn't have to be eg.globals.VARNAME it can be just VARNAME
- caffeinatedcoder
- Posts: 20
- Joined: Wed Jul 06, 2016 4:56 pm
Re: Will an error in a Python Script Action stop a Macro?
Wow, that seems like a lot to remember at this moment. Since I already have an edited version of my code, is there any way you could give me some feedback on how that would perform? I mean, I don't need it to be top-of-the-line code as long as it'll get the job done for this one action.
pro┬Àgram┬Àmer (n) An organism capable of converting caffeine into code.
- kgschlosser
- Site Admin
- Posts: 5190
- Joined: Fri Jun 05, 2015 5:43 am
- Location: Rocky Mountains, Colorado USA
Re: Will an error in a Python Script Action stop a Macro?
this is untested. so give it a shot. it would be a type if it doesn't work. the idea behind how it's coded is sound.
i commented it like crazy so you can get a better understanding of what is going on. and that is actually the bulk of the code. you do not have to leave the comments in there if you don't want to.
enjoy
K
i commented it like crazy so you can get a better understanding of what is going on. and that is actually the bulk of the code. you do not have to leave the comments in there if you don't want to.
enjoy
K
Code: Select all
from os import path
DELETED_PATH = 'c:\\DeletedDirectory%d'
ATTR_NAMES = [ 'PDEV', 'PubESPA ', 'PubASIR', 'DWNLDS', 'DOCS', 'SCRNSHTS']
# since the directory is a constant and the only thing that changes is
# the number on the end of the path we can iterate through a list of the eg.global names
# and use that to count which index we are on my using the enumerate
# we do have to add one to the index number because a list index starts at 0,
# and the directories start at 1
for i, attrName in enumerate(ATTR_NAMES):
# Test if directories still exists adding that number onto the end + 1
attr = path.exists(DELETED_PATH % i + 1)
# Create the eg.globals attribute since the end of the variable name is the same
# we don't have to have that in our list of names we add it here
setattr(eg.globals, attrName + 'directory', attr)
# now we do out check to see if it was sucessful or not and instead of printing i decided to
# trigger an event. just in cause you wanted to do something if it succeeded or failed.
if attr:
suffix = '%s.SuccessfullyScrubbed'
else:
suffix = '%s.FailedBeingScrubbed'
eg.TriggerEvent(prefix='Directory', suffix=suffix % attrName)
-
m19brandon
- Experienced User
- Posts: 177
- Joined: Mon Feb 03, 2014 10:36 pm
Re: Will an error in a Python Script Action stop a Macro?
I like to set EG.result none at the start of all my macros and then set it true or false in my Python Scripts and then check the state through out my macros. This prevents and stops the macros as needed. I now also know I made mistake because my end action never completes.
-
krambriw
- Plugin Developer
- Posts: 2570
- Joined: Sat Jun 30, 2007 2:51 pm
- Location: Stockholm, Sweden
- Contact:
Re: Will an error in a Python Script Action stop a Macro?
Another way of running python scripts that I prefer is to use the built in eg.scheduler. If you schedule a python function call (instead of immediate execution) it will run in a separate thread. I gave example here in another topic
http://eventghost.net/forum/viewtopic.p ... 020#p43004
http://eventghost.net/forum/viewtopic.p ... 020#p43004
My released plugins
https://drive.google.com/drive/folders/ ... y01eVBKeHM
https://drive.google.com/drive/folders/ ... y01eVBKeHM
