Getting error using sys.exit() or exit()

I've used sys.exit() function to get exit from script if certain conditions becomes true as given below:
if (condition):
import sys
logged message
sys.exit()

When this condition is satisfies, the message is getting logged in Ignition logs and also script is getting exit from the script by skipping later code in the script.
But in the log getting message as E Dispatcher
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 104, in valueChanged SystemExit

at org.python.core.PySystemState.exit(PySystemState.java:1523)

at org.python.core.PySystemState.exit(PySystemState.java:1530)

at jdk.internal.reflect.GeneratedMethodAccessor1299.invoke(Unknown Source)

at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.base/java.lang.reflect.Method.invoke(Unknown Source)

at org.python.core.PyReflectedFunction.call(PyReflectedFunction.java:188)

at org.python.core.PyReflectedFunction.call(PyReflectedFunction.java:206)

at org.python.core.PyObject.call(PyObject.java:480)

at org.python.core.PyObject.call(PyObject.java:484)

at org.python.core.PyMethod.call(PyMethod.java:126)

at org.python.pycode._pyx658427.valueChanged$1(:178)

at org.python.pycode._pyx658427.call_function()

at org.python.core.PyTableCode.call(PyTableCode.java:171)

at org.python.core.PyBaseCode.call(PyBaseCode.java:308)

at org.python.core.PyFunction.function___call__(PyFunction.java:471)

at org.python.core.PyFunction.call(PyFunction.java:466)

at org.python.core.PyFunction.call(PyFunction.java:461)

at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:836)

at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:820)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:687)

at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$FunctionInvokerImpl.run(TagScriptManagerImpl.java:530)

at com.inductiveautomation.ignition.gateway.tags.scripting.events.AbstractTagScript.invoke(AbstractTagScript.java:34)

at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$Task.invoke(TagScriptManagerImpl.java:479)

at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$TagScriptDispatcher.run(TagScriptManagerImpl.java:442)

at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$ThrowableCatchingRunnable.run(BasicExecutionEngine.java:538)

at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.base/java.lang.Thread.run(Unknown Source)

Caused by: org.python.core.PyException: Traceback (most recent call last): File "", line 104, in valueChanged SystemExit

... 31 common frames omitted
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
I've also tried using exit() and observed same thing.
This error is getting logged only once so I'm confused whether this method of using exit() or sys.exit() to exit code is valid in Ignition or not?

Just use return to beak from the function.


def someFunction():
    if condition:
        #do something
        return
    elif someOtherCondition:
        #do something else
        return

    #fall through and do any last chance operation
    return

I'm not using any function, directly written script on tag on "value change" event.

But you are. The valueChanged event is a function, Ignition just puts the function signature in for you because it needs to be specific.

def valueChanged(tag, tagPath, preiousValue, currentValue, initialChange, missedEvents):
    if initialChange:
        return
4 Likes

Ohh thats correct. But why getting error only first time after using sys.exit() or exit() ?
When the condition triggers next time it does not log that error.

You're probably shutting down the scripting 'engine' in the background that's responsible for running your code, and it's not restarted until the next time you make changes to the script.

Basically - never use exit() or sys.exit() in Ignition. If you want to exit the current application, use system.util.exit().

3 Likes

Are there any better way to exit from e.g. actionPerformed button component script ?

eg.

`

import sys
if event.source.xSpecialProperty == 0:
	system.gui.messageBox(u"Special property not settled","Warn")
	  sys.exit()

#rest of code

is only proper way to move it to internal function and return ?

def action(event):
	if event.source.xSpecialProperty == 0:
		system.gui.messageBox(u"Special property not settled","Warn")
		return

	#rest of code
action(event)

You don’t need the internal function.

Component scripts, really any scripts, are already functions.

Just returning in the scope of the if will work.

The return is saying I have finished my work return to the caller. No code in a function following a return will be executed. It ends the execution path.

In reality you are returning none, so any caller that is expecting a value back will receive a null value.

Cannot save script with return without function.

In jython, the return statement requires a function:
Disregard. I didn't see the overall context of the conversation

Not true in Vision, for actual events. Nor older project events. Custom methods and extension methods are functions.

No. Moving the logic to a project script library is the right answer. Which you should do anyways, to avoid legacy scoping issues in project events. And make your code more maintainable.

1 Like

I stand corrected.