# Script Benchmarking with Decorators Example

**URL:** <https://forum.inductiveautomation.com/t/script-benchmarking-with-decorators-example/63507>\
**Category:** Ignition\
**Tags:** ignition81, scripting\
**Created:** [August 26, 2022, 4:46pm UTC](https://forum.inductiveautomation.com/t/script-benchmarking-with-decorators-example/63507 "2022-08-26T16:46:11Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [January 24, 2023, 3:30pm UTC](https://forum.inductiveautomation.com/t/script-benchmarking-with-decorators-example/63507/4 "2023-01-24T15:30:28Z")

</div>

I wanted to try to write a generic error handling decorator, so I gave it a shot. I probably committed an unforgivable sin somewhere lol.

@pturmel 's later.py has a `PythonAsJavaException` class if you want to use a logger. I just did a print to test with.

```auto
from java.lang import Throwable
import traceback

class errorHandler():
	''' decorator to wrap functions with a generic error handler '''

	def handleError(self, fn, values, trace):
		fnName = fn. __name__
		args = dict( zip( fn.func_code.co_varnames[:fn.func_code.co_argcount], values['args'] + fn. __defaults__ ) )								
		gateway = system.tag.readBlocking(["[System]Gateway/SystemName"]).value
		exception = 'Call to %s() failed with an exception \n Args: %s \n Kwargs: %s \n %s' % (fnName, args, values['kwargs'], trace)
		print exception
	
	def __call__ (self, fn):
		# returns the decorator itself, which accepts a function and returns another function
		# wraps ensures that the name and docstring of 'fn' is preserved in 'wrapper'
		@functools.wraps(fn)
		def wrapper(*args, **kwargs):
			# the wrapper passes all parameters to the function being decorated		
			try:
				return fn(*args, **kwargs)
			except Exception, e:
				self.handleError(fn, locals(), traceback.format_exc()) #(later.PythonAsJavaException(e)
				return None
			except Throwable, t:
				self.handleError(fn, locals(), traceback.format_exc()) #later.PythonAsJavaException(t))
				return None
		return wrapper

```

Python exception example

```auto
@errorHandler()
def exceptionTest(x, y, override = 4, **kwargs):	
	z = x / y
	system.db.runNamedQuery('Unknown', {'z':z})
	
exceptionTest(4,0, test=True)

```

results

```auto
Call to exceptionTest() failed with an exception 
 Args: {'x': 4, 'y': 0, 'override': 4} 
 Kwargs: {'test': True} 
 Traceback (most recent call last):
  File "<module:util>", line 175, in wrapper
  File "<input>", line 3, in exceptionTest
ZeroDivisionError: integer division or modulo by zero

```

Java throwable example

```auto
@errorHandler()
def exceptionTest(x, y, override = 4, **kwargs):	
	z = x / y
	system.db.runNamedQuery('Unknown', {'z':z})
	
exceptionTest(4,1, test=True)

```

results

```auto
Call to exceptionTest() failed with an exception 
 Args: {'x': 4, 'y': 1, 'override': 4} 
 Kwargs: {'test': True} 
 Traceback (most recent call last):
  File "<module:util>", line 175, in wrapper
  File "<input>", line 4, in exceptionTest
Exception: java.lang.Exception: Did not find query Unknown in project resources.

```

---

_[View the full topic](https://forum.inductiveautomation.com/t/script-benchmarking-with-decorators-example/63507)._
