Mit dem Command Engineering.AbortExecutionIfErrorCommand kann die Bearbeitung einer Aktion abgebrochen werden, falls ein Skript einen Fehler in den UserMessageCollector eingetragen hat.
Folgendes Beispiel zeigt das Szenario für ein anskizziertes komplexeres Skript. Bei einem Fehler soll das Skript-Ergebnis (d.h. die erzeugten Änderungen am Modell) nicht gespeichert werden. Die zugehörige Action sieht so aus:
Im zugehörigen ScriptCommand wird im Fehlerfall nun einerseits ein Fehler in den UserMessageCollector eingetragen, als auch die interne rekursive und iterative Skript-Bearbeitung sauber abgebrochen. Dies kann entweder ohne Verwendung von Ausnahmen über ein Skript-globales abortExecution-Flag geschehen, oder mittels der UserScriptException. Der UserScriptException muss eine ID und optional ein Text mitgegeben werden. Dadurch können innerhalb von Skripten verschiedene Abbruchbedingungen behandelt werden. Dies funktioniert auch bei Aufrufen von Skripten in Skripten. Eine, in einem Unterskript geworfene, Ausnahme kann im aufrufenden Skript behandelt werden.
import org.foederal.util.ui.messages.UserMessageCollector;
import com.mind8.mechatronic.skill.eos.MechatronicObject;
import com.mind8.mechatronic.skill.eos.MechatronicComponent;
void doWork1(MechatronicComponent mc)
{
children = mc.getMechatronicObjects();
for (Iterator iter = children.iterator() ;iter.hasNext();)
{
child = iter.next();
// define any abnormal abort condition
if (child.getName().equals("unknown"))
{
// log error and abort recursion
// don't forget to test for error by including an
// AbortExecutionIfErrorCommand in the Action
UserMessageCollector.addError(LIBRARY,self,null,"Skript","Encountered unknown object! Aborting ...");
super.abortExecution = true;
return;
}
else
{
UserMessageCollector.addInfo(LIBRARY,self,null,"Skript","Processing " + child.getName());
// do something ...
if (child instanceof MechatronicComponent)
{
// a mc has children, so go into recursion
doWork1(child);
}
}
// abort iteration in case of abortion in recursion
if (super.abortExecution) return;
}
}
void doWork2(MechatronicComponent mc)
{
// do something
}
// main script
abortExecution = false;
for (Iterator iter = obj.getMechatronicComponents().iterator() ;iter.hasNext();)
{
mc = iter.next();
doWork1(mc);
// check abort in doWork1
if (abortExecution) return;
doWork2(mc);
// check abort in doWork2
if (abortExecution) return;
}
import com.mind8.mechatronic.skill.scripting.UserScriptException;
import org.foederal.util.ui.messages.UserMessageCollector;
import com.mind8.mechatronic.skill.eos.MechatronicObject;
import com.mind8.mechatronic.skill.eos.MechatronicComponent;
void doWork1(MechatronicComponent mc)
{
children = mc.getMechatronicObjects();
for (Iterator iter = children.iterator() ;iter.hasNext();)
{
child = iter.next();
// define any abnormal abort condition)
if (child.getName().equals("unknown"))
{
// Throw UserScriptAbortException to end recursion.
// Don't forget to test for error by including an
// AbortExecutionIfErrorCommand in the Action
throw new UserScriptException("id_abort","Encountered unknown object! Aborting ...");
}
else
{
UserMessageCollector.addInfo(LIBRARY,self,null,"Skript","Processing " + child.getName());
// do something ...
if (child instanceof MechatronicComponent)
{
// a mc has children, so go into recursion
doWork1(child);
}
}
}
}
void doWork2(MechatronicComponent mc)
{
// do something
}
// main script
try
{
for (Iterator iter = obj.getMechatronicComponents().iterator();
iter.hasNext();)
{
mc = iter.next();
doWork1(mc);
doWork2(mc);
}
}
catch (UserScriptException e)
{
// only handle desired aborts
if (e.getId().equals("id_abort"))
{
UserMessageCollector.addError(LIBRARY,self,null,"Skript",e.getMessage());
}
else
{
// handle elsewhere
throw e;
}
}