# Function full path

**URL:** <https://forum.inductiveautomation.com/t/function-full-path/77922>\
**Category:** Ignition\
**Created:** [August 16, 2023, 10:38am UTC](https://forum.inductiveautomation.com/t/function-full-path/77922 "2023-08-16T10:38:57Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ajay\_Gupta](https://avatars.discourse-cdn.com/v4/letter/a/f05b48/32.png) [@Ajay\_Gupta](https://forum.inductiveautomation.com/u/Ajay_Gupta)\
**Post date:** [August 16, 2023, 10:38am UTC](https://forum.inductiveautomation.com/t/function-full-path/77922/1 "2023-08-16T10:38:57Z")

</div>

Hello,

Is there a way to get the complete path of a function?  
Example:  
Let's say I have a function defined inside "Scripts \> DB \> "FunctionName".  
So, When an error occurs within FunctionName, I want to log "Scripts.DB.FunctionName" as the originator of the error.

Right now I am using "inspect.currentframe()" method of inspect library but this only gives me the name of the function without the path of the script file in which the function exists.  
inspect.currentframe() returns FunctionName but I want "Scripts.DB.FunctionName".

Thanks,  
Ajay

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 16, 2023, 2:36pm UTC](https://forum.inductiveautomation.com/t/function-full-path/77922/2 "2023-08-16T14:36:47Z")

</div>

I'm not sure I understand what you want...

Let's say you have a script called `Foo` which contains a function called `bar`.  
`bar` raises an error, which you catch from some other functions.  
You want to log the full path of `bar` from that `except` clause, is that it ?  
you can use

```python
func. __code__.co_filename

```

to get the path of the module where the function is, then append the function name to it

```python
func. __name__

```

---

<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:** [August 16, 2023, 2:57pm UTC](https://forum.inductiveautomation.com/t/function-full-path/77922/3 "2023-08-16T14:57:51Z")

</div>

I use something like this

```auto
class errorHandler():
	''' decorator to wrap functions with a generic error handler '''
	def handleError(self, fn, values, trace):
		# Format the failed call into the same format that it would written in code
		try: fnPath = '%s.%s' % (fn.func_code.co_filename.split(':')[1].replace('>',''), fn. __name__ )
		except: fnPath = fn. __name__
		
		argsFmt = ','.join(['%r' % x for x in values['args']])
		kwargsFmt = ','.join(['%s=%r' % (k,v) for k,v in values['kwargs'].items()])
	
		callString = '%s(%s)' % (fnPath, ','.join(filter(None,(argsFmt,kwargsFmt))))

        # do something with the failed function path here
	
	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 (Throwable, Exception) as e:
				self.handleError(fn, locals(), traceback.format_exc())
				return {'ErrMsg':e}
				
		return wrapper

```

```auto
# decorator to apply the error handler wrapper to any function we want
@errorHandler() 
def someFunction():
    return value

```

---

<div class="post-metadata">

**Author:** ![tyler.bennett](https://avatars.discourse-cdn.com/v4/letter/t/f04885/32.png) [@tyler.bennett](https://forum.inductiveautomation.com/u/tyler.bennett)\
**Post date:** [June 9, 2025, 4:55am UTC](https://forum.inductiveautomation.com/t/function-full-path/77922/4 "2025-06-09T04:55:07Z")

</div>

To directly respond to the OP's question

```python
inspect.currentframe().f_code.co_name # the name of the current function
inspect.currentframe().f_code.co_filename # the module the current function is in
inspect.currentframe().f_back.f_code.co_name # the name of the calling function
inspect.currentframe().f_back.f_code.co_filename # the module calling the function is in

```

An easy way to spit out both (function name and module) when handling an exception is:

```python
traceback.format_exc()

```

An easy way to spit out both when not handling an exception is:

```python
traceback.format_stack(limit=1)

```

@dkhayes117, looks like I need to get familiar with decorators.
