I’m trying to code a generic type of error handler that I can call from the except
clauses from different scripts where the error_handler
procedure can take different routes depending on what is passed to it.
Ideally, I want a generic error handler that will catch any/all types of errors.
My question is, will the str(e)
in the except
clause below work correctly for all or most types of errors?
try:
i = 1 / 0 # divide by zero error
except Exception as e:
error_handler(str(e)) # will this line str(e) work for all errors?
We have tons of error handling where the except clauses look like (see image below) from a UDT Tag Value Change
script.
I want to replace this code (code that builds parameters, calls Named Query and logs to the database)
I want to replace it with a single line code like error_handler()
(see my original post above) where the error_handler
procedure can take different routes depending on what is passed to it.
The error_handler()
procedure will be in a script procedure that is in an inheritable/parent project
For some reason, the code like getattr(e, 'message', repr(e))
throws me for a bit of a loop, possibly making me think the error handling is more complicated than it really is? My experiments using str(e)
seem to work correctly. I think I just need someone else to tell me ha
getattr(e, 'message',
repr(e))
is retrieving the property named message
from e
, and if e
does not have a message
property, it’s returning repr(e)
. repr
can be distinct from str
, but usually won’t be for Java objects, including exceptions. It’s not clear from your snippet if Exception
is Python’s built-in Exception type or Java’s; someone may be importing from java.lang import Exception
earlier in that script.
I no longer use from java.lang import Exception
. I use from java.lang import Throwable
instead. Python’s Exception
will not catch java exceptions at all. Java’s Throwable
will not catch any python exceptions. You must have two separate except
clauses everywhere.
See also the PythonAsJavaException
class in my later.py
script–necessary if you want to push python stack traces into Ignition loggers.
3 Likes
What about
import traceback
traceback.format_exc()
Phil? Does this miss something?
It doesn’t play nice with the logging system. For loggers to deliver a neat traceback, you have to supply a subclass of java’s Throwable
.
1 Like
Thank you, yes, the (message
) property of the e
object. You mentioned that (if e
does not have a message
property). What types of errors or when would e
not have the message
property?
My snippet is from an Ignition UDT script. There are not any (from java.lang import Exception
) lines, or anything similar in the scripts.
Can you give an example of what that would look like (two except clauses).
I want to catch errors on system.tag.write, and try: / except: is not catching the error.
The vision client user does not have writePermissions for the first tag in this list, so I want the whole
routine to end. I'm printing to the console to debug what is happening, and I still get an error popup on the client, and I never get the "Error occurred" message in the console which indicates the Except code is NOT RUNNING.
Here is my code:
That's because a write that fails is not an error per se. You need to store the return from each write and check if the value is good or not
4 Likes
As Nick said, a failed write doesn't raise an exception, so there's nothing to catch.
I use this to check for failed writes:
base_logger = system.util.getLogger("Utils").createSubLogger("Tags")
def write(paths, values, logger=None):
if logger is None:
logger = base_logger
write_return = system.tag.writeBlocking(paths, values)
bad_writes = ["{} ({})".format(path, quality) for path, quality in zip(paths, write_return) if not quality.good]
if bad_writes:
logger.warn("failed writes: {}".format(bad_writes))
This logs a warning with the path and quality of every failed writes. You might want to rework it a bit to match your needs.