Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReGaHSS: foreach [12/12 BP-14] -> Schleifenabbruch bei ScriptRuntimeError in der Schleife #2623

Open
BadenPower opened this issue Jan 17, 2024 · 14 comments
Labels
🐛 bug-report Something isn't working 🏷️ ReGaHss This refs the ReGaHss component ❓ undecided No decision to accept or reject ticket yet

Comments

@BadenPower
Copy link

Describe the issue you are experiencing

Wird die foreach-Anweisung aufgerufen und es tritt ein Laufzeitfehler in der direkten Schleifenebene auf, dann werden die restlichen Schleifedurchläufe nicht mehr ausgeführt. Ausserdem wird die Ausführung des kompletten Skriptes abgebrochen sofern die Ausführungsebene der Schleife auf der Hauptebene des Skriptes liegt.

Describe the behavior you expected

Erwartet wurde das Ausführen der weiteren Schleifendurchläufe, wie es bis ReGaHss-Version R1.00.0388.0109 der Fall war.

Steps to reproduce the issue

Ausführung des folgenden Skriptes unter "Skript testen":

WriteLine("Start");
WriteLine(dom.BuildLabel());
string lList = "1;2;65535;700;950";
string lEnum;
object lObj;
foreach(lEnum,lList.Split(";"))
{
  WriteLine("------------------------------------------------------------");
  WriteLine(lEnum);
  lObj = dom.GetObject(lEnum);
  WriteLine(lObj.Name());
  WriteLine("Block-Ende");
}
WriteLine("------------------------------------------------------------");
WriteLine("Ende");

What is the version this bug report is based on?

CCU3 mit ReGaHSS-Version R1.00.0388.0235

Which base platform are you running?

rpi3 (RaspberryPi3)

Which HomeMatic/homematicIP radio module are you using?

n/a

Anything in the logs that might be useful for us?

bestehend seit:
ab ReGaHss-Version R1.00.0388.0109 (18.05.2017)

Additional information

Ausgabe mit ReGaHss-Verion R1.00.0388.0108:

Start
R1.00.0388.0108
------------------------------------------------------------
1
DOM
Block-Ende
------------------------------------------------------------
2
Root
Block-Ende
------------------------------------------------------------
65535
null
------------------------------------------------------------
700
AlarmMaps
Block-Ende
------------------------------------------------------------
950
${sysVarPresence}
Block-Ende
------------------------------------------------------------
Ende

Ausgabe mit ReGaHss-Verion R1.00.0388.0235:

Start
R1.00.0388.0235
------------------------------------------------------------
1
DOM
Block-Ende
------------------------------------------------------------
2
Root
Block-Ende
------------------------------------------------------------
65535
null
@BadenPower BadenPower added the 🐛 bug-report Something isn't working label Jan 17, 2024
@HMMike
Copy link

HMMike commented Jan 18, 2024

Ich kenne es aus anderen Sprachen so

Runtimeerror entweder in ein exception handling [hat hm script nicht) oder raus mit runtimeerror.

Folglich ist in meinen Augen das jetzige Handling konsistent, das frühere nicht

@jens-maus
Copy link
Owner

Ehrlich gesagt tendiere ich auch dazu das jetzige Verhalten (Abbruch der Schleifendurchgänge bei einem Runtime Error) als "richtiger" bzw. erstrebenswerter anzusehen. Warum genau sollte man bzw. sollte die foreach() Schleife weiterarbeiten wenn ein offensichtlicher Fehler (hier der fehlende null check des Returnwertes von dom.GetObject()) im Skript existiert?

@jens-maus jens-maus added 🏷️ ReGaHss This refs the ReGaHss component ❓ undecided No decision to accept or reject ticket yet labels Jan 19, 2024
@BadenPower
Copy link
Author

Da die ReGaHss bzw. die Script-Engine für die Skript-Ausführung intern mit einer block-geschützten Fehlerbehandlung arbeitet (welche es dem Scriptprogrammierer erlaubt ein ausgefeiltes Error-Handling ala "try/except" oder "try/finally" zu realisieren), durchbricht dieser Bug die gültigen "Konvetionen", in der ein auftretender ScriptRuntimeError in einem Block niemals die Ausführung in einem anderen Block der gleichen oder übergeordneten Ebene abbricht.

Daher sollte die Schleife, wie es bis ReGaHss-Version R1.00.0388.0108 üblich war, auch weiterhin ausgeführt werden.

Den Abbruch der Schleife kann man durchaus auch momentan in den neuen ReGaHss-Versionen durch den Einsatz von Error-Handling im Skript unterbinden. Dennoch wäre es wünschenswert, wenn dies wieder durch die ReGaHss selbst erledigt würde.

@jens-maus
Copy link
Owner

jens-maus commented Jan 19, 2024

@BadenPower Tut mir leid, aber ich bin da aktuell immer noch nicht davon überzeugt ob man das so umsetzen sollte (wenn man es denn überhaupt kann). Bitte zeige mal ein konkretes (bitte einfaches) Beispiel wo du denkst das es von Vorteil wäre wenn trotz eines ScriptRuntimeError innerhalb eines foreach() Blockes er trotzdem weiter iterieren sollte bis zum Ende der foreach-Bedingung. Ich kann mir nämlich nicht gerade wirklich einen Fall ausdenken wo das von Vorteil wäre – sondern eben umgedreht erscheint es mir viel mehr von Vorteil zu sein das foreach und while bei einem auftretenden ScriptRuntimeError entsprechend die Schleife abbricht und damit die Programmausführung so schnell wie möglich beendet.

@HMMike
Copy link

HMMike commented Jan 20, 2024

Ich halte wie gesagt das jetzige Verhalten für konsistent.
Wir haben keinen try except zum Fehlerfangen folgerichtig ist ein scriptruntimeerror auch ein scriptabbruch.

Genial wäre natürlich ein try except bzw try finally auch auf der scriptebene. Das wäre aber Jens sein Job.

@MichaelN0815
Copy link
Contributor

BadenPower will vermutlich andeuten, das es so einen Mechanismus (undokumentiert) gibt

intern mit einer block-geschützten Fehlerbehandlung arbeitet (welche es dem Scriptprogrammierer erlaubt ein ausgefeiltes Error-Handling ala "try/except" oder "try/finally" zu realisieren)

@BadenPower
Copy link
Author

BadenPower commented Jan 20, 2024

Ich halte wie gesagt das jetzige Verhalten für konsistent.

Dieses Verhalten ist alles andere als konsistent, denn es gibt keinen einzigen Fall, bei dem ein ScriptRuntimeError welcher nicht auf der Hauptebene des Skriptes ausgelöst wird, zum Abbruch des Skriptes führt.

Aussnahmen sind nur die beiden Fälle von foreach und while (wäre der nächste Bug-Report gewesen), aber dies eben nicht von Anfang an, sondern als ungeprüfter Side-Effect durch Reparaturmaßnahmen in der Version R1.00.0388.0109.

Vor dieser Änderung hielten sich auch die beiden Anweisungen foreach und while daran, ein Skript nicht zu beenden, wenn in der Schleifenebene ein SkriptRuntimeError auftritt.

Somit ist dieses Verhalten ein klarer Bug.

Ausserdem findet der Skript-Abbruch ja auch nur statt, sofern sich die foreach- oder while-Scheife auf der Hauptebene befinden. Noch ein klares Anzeichen für ein inkosistentes Verhalten seit der Änderung.

Wir haben keinen try except zum Fehlerfangen folgerichtig ist ein scriptruntimeerror auch ein scriptabbruch.
Genial wäre natürlich ein try except bzw try finally auch auf der scriptebene. Das wäre aber Jens sein Job.

Nein, das ist nicht der Job von Jens, denn die Script-Engine der ReGaHss macht dies automatisch und hat es auch für foreach und while so gemacht, bis Änderungen vorgenommen wurden und das interne Konzept inkonsistent gemacht hat.

Wie ich oben bereits schrieb, kann der Skriptprogrammierer immernoch die Schleife zum weiterlaufen bewegen, in dem er eben selbst im Skript das Error-Handling einsetzt.

BadenPower will vermutlich andeuten, das es so einen Mechanismus (undokumentiert) gibt

intern mit einer block-geschützten Fehlerbehandlung arbeitet (welche es dem Scriptprogrammierer erlaubt ein ausgefeiltes Error-Handling ala "try/except" oder "try/finally" zu realisieren)

Da brauche ich doch nichts andeuten, denn die Vorgehensweise sollte allgemein bekannt sein.

@jens-maus
Copy link
Owner

jens-maus commented Jan 21, 2024

@BadenPower

Aussnahmen sind nur die beiden Fälle von foreach und while (wäre der nächste Bug-Report gewesen)...

Wenn du vor hast die exakt gleichen Probleme die du für foreach bereits gemeldet hattest jetzt im Kontext von while zu melden, dann geh bitte hin und erweitere stattdessen die existieren Issuereports um den Hinweis, das diese auch für while zutreffen, statt hier eine Trennung vorzunehmen und diese Probleme noch einmal zu melden.

BadenPower will vermutlich andeuten, das es so einen Mechanismus (undokumentiert) gibt

intern mit einer block-geschützten Fehlerbehandlung arbeitet (welche es dem Scriptprogrammierer erlaubt ein ausgefeiltes Error-Handling ala "try/except" oder "try/finally" zu realisieren)

Da brauche ich doch nichts andeuten, denn die Vorgehensweise sollte allgemein bekannt sein.

Dies ist zumindest mir und offensichtlich auch anderen nicht allgemein bekannt bzw habe ich das aktuell nicht auf dem Schirm. Bitte halte daher keine Informationen hinter dem Berg oder setze gewisses Detailwissen voraus. Bitte untermauere deine Argumentationen mit konkreten, ausführlichen Skriptbeispielen die demonstrieren worum es dir hier in diesem Issueticket geht. Aus dem oben gezeigten Beispiel alleine wird eben nicht wirklich ersichtlich warum man eine foreach oder while Schleife weiterlaufen lassen sollte wenn ein ScriptRuntimeError auftritt. Bitte untermauere daher deine Argumentationen mit mehr Skriptbeispielen und Detailinformationen damit vor allem ich Deinen Argumentationen besser/einfacher folgen kann um mir somit ein umfassenderes Bild der Situation machen zu können bevor ich eine finale Entscheidung über dieses Issueticket hier treffe.

@HMMike
Copy link

HMMike commented Jan 21, 2024

EIn RuntimeError ist nun mal ein RuntimeError und benötigt ein vom Programmierer bewusst eingesetztes Handling.
Folglich ist für mich das alte Verhalten konsistent, dass ein Abbruch erfolgen würde.

Bei geschachtelten Schleifen tuts das wiederrum nicht, ein Fehler in der Inneren Schleife wirft den SRE und beendet die innere Schleife, das Programm wird aber an der äusseren Schleife fortgesetzt. Da stimmt wohl was mit den Stacks nicht

Entweder alles Scriptruntimeerror oder alles ignorieren, aber nicht Abhängig von der Stacktiefe.

Im übrigen ist folgender, hochgeheimer Effekt gemeint, mit folgendem Konstrukt lässt sich das darstellen:

integer a;
string endelimitier="__ENDE__" ;
foreach (a,1) {
  string s;
  string v="AllwaysTrue\tBÄNG\t"#endelimitier;
!  string v="AllwaysTrue\t"#endelimitier;
  if (a==1) {
     foreach (s,v) {
         WriteLine (dom.GetObject(s).State());
     }
  }
  WriteLine (s);
  if (s!=endelimitier) {WriteLine ("Hier hats geknallt bei s="#s); !Hier stünde ein Fehlerhandling }
}

In meinem Fall gibts AllwayTrue als Sysvar, aber BÄNG nicht und dort knallts dann auch.
nur Das hier das Script halt weiterläuft. Da aber wie gesagt dies eigentlich ein inkosistentes Verhalten ist, dessen implementierung nirgends dokumentiert ist und sich so auch jederzeit ändern kann, habe ich immer auf diesen EInsatz bewusst verzichtet.

Nichts desto trotz muss ich Jens aber auch recht geben, Das lässt sich elegant unter dem Oberbegriff "Schleifenhändling" zusammenfassen und muss nicht einzeln aufgebläht aufgeführt werden

@jens-maus
Copy link
Owner

Bei geschachtelten Schleifen tuts das wiederrum nicht, ein Fehler in der Inneren Schleife wirft den SRE und beendet die innere Schleife, das Programm wird aber an der äusseren Schleife fortgesetzt. Da stimmt wohl was mit den Stacks nicht

Entweder alles Scriptruntimeerror oder alles ignorieren, aber nicht Abhängig von der Stacktiefe.

Nun, das ist natürlich zum Teil den "Eigenheiten" der Implementierung der Skriptsprache geschuldet. Ein ScriptRunTimeError operiert mitunter nur innerhalb des Kontextes in dem er auftritt. Und in dem Falle ist das dann eben die jeweilige "Schleife" oder "Funktion". Es werden bei einem ScriptRunTimeError ja auch noch die komplette Scriptausführung global über die gesamte ReGaHss abgebrochen, sondern eben lediglich der Teil in dessen Kontext sich die ReGa – die ja single-threaded operiert – gerade befindet. Insofern halte ich das sehr wohl für konsistent.

Im übrigen ist folgender, hochgeheimer Effekt gemeint, mit folgendem Konstrukt lässt sich das darstellen:
[...]

Wenn @BadenPower das wirklich gemeint hat, so erscheint mir das vielmehr ein Methode zu sein um herauszukommen das ein Schleifendurchlauf zum Ende gekommen ist oder nicht und weniger ein try/except like konstrukt zu sein wie das bei andere modernen Programmiersprache so der Fall ist.

In meinem Fall gibts AllwayTrue als Sysvar, aber BÄNG nicht und dort knallts dann auch.

Nun, auch aus diesem Script kann ich nicht wirklich herauslesen warum man es haben wollen würde das die foreach() schleife im Falle eines ScriptruntimeError weiterläuft und seine weiteren Iterationen noch durchführt. Ich sehe hier lediglich das im Grunde derjenige der diesen Skript geschrieben hat leider vergessen hat die eigentlich immer notwendige Prüfung auf null nach einem GetObject() umzusetzen. Denn wäre dort z.B. eine null Prüfung mit einem entsprechenden break oder continue statement, dann wäre doch alles ok und der Skript würde so operieren wie vom Entwickler gewollt. Deshalb kann ich mir leider immer noch nicht einen Fall ausmahlen wo man wöllte das ein foreach oder whileweiterläuft trotz der tatsache das innerhalb seine Kontextes ein offensichtlicher Fehler aufgetreten ist.

@HMMike
Copy link

HMMike commented Jan 21, 2024

@jens-maus
Ich stimme dir da eigentlich komplett zu.

bis auf: innere und äussere Schleife sollten sich gleich verhalten bei einem Scriptruntimeerror.

@BadenPower
Copy link
Author

Um hier mitzudiskutieren setze ich natürlich darauf, dass die Beiteiligten ein hohes Mass an Erfahrung in der Skript-Programmierung sowie auch den gegebenen Verhaltensweisen der ReGaHss mitbringen.

Sollte daher etwas unklar sein, dann muss einfach nachfragt werden.

Fangen wir einmal mit den einfachsten Grundlagen an:

Testskript 1

WriteLine("Start");
object lObj;
if(lObj.Name())
{
  WriteLine("Block");
}
WriteLine("Ende");

Ausgabe mit ReGaHss-Verionen R1.00.0388.0108 und R1.00.0388.0235

Start
Ende

Wie zu sehen ist, wird das Testskript 1 weder mit ReGaHss-Verionen R1.00.0388.0108 noch R1.00.0388.0235 abgebrochen Es werden lediglich die weiteren Skriptzeilen im Block ab dem Zeitpunkt des Auslösens des ScriptRuntimeError nicht mehr weiterverarbeitet.

Testskript 2

WriteLine("Start");
string lResult;
object lObj;
boolean Try = true;
integer lErrors = 0;
if(Try)
{
  lErrors = lErrors + 1;
  WriteLine("Block-Begin");
  lResult = lObj.Name();
  WriteLine("Block-Ende");
  lErrors = lErrors - 1;
}
if(lErrors > 0)
{
  WriteLine("Es ist/sind " # lErrors # " Laufzeitfehler aufgetreten");
}
WriteLine("Ende");

Ausgabe mit ReGaHss-Verionen R1.00.0388.0108 und R1.00.0388.0235

Start
Block-Begin
Es ist/sind 1 Laufzeitfehler aufgetreten
Ende

Wie zu sehen ist, wird das Testskript 2 weder mit ReGaHss-Verionen R1.00.0388.0108 noch R1.00.0388.0235 abgebrochen Es werden lediglich die weiteren Skriptzeilen im Block ab dem Zeitpunkt des Auslösens des ScriptRuntimeError nicht mehr weiterverarbeitet.

Testskript 3

WriteLine("Start");
string lList = "1;2;65535;700;950";
string lEnum;
object lObj;
boolean Try = true;
integer lErrors = 0;
foreach(lEnum,lList.Split(";"))
{
  if(Try)
  {
    lErrors = lErrors + 1;
    WriteLine("------------------------------------------------------------");
    WriteLine(lEnum);
    lObj = dom.GetObject(lEnum);
    WriteLine(lObj.Name());
    WriteLine("Block-Ende");
    lErrors = lErrors - 1;
  }
}
WriteLine("------------------------------------------------------------");
if(lErrors > 0)
{
  WriteLine("Es ist/sind " # lErrors # " Laufzeitfehler aufgetreten");
}
WriteLine("Ende");

Ausgabe mit ReGaHss-Verionen R1.00.0388.0108 und R1.00.0388.0235

Start
------------------------------------------------------------
1
DOM
Block-Ende
------------------------------------------------------------
2
Root
Block-Ende
------------------------------------------------------------
65535
null
------------------------------------------------------------
700
AlarmMaps
Block-Ende
------------------------------------------------------------
950
SYS-CCU-Reboot
Block-Ende
------------------------------------------------------------
Es ist/sind 1 Laufzeitfehler aufgetreten
Ende

Wie zu sehen ist, wird das Testskript 3 weder mit ReGaHss-Verionen R1.00.0388.0108 noch R1.00.0388.0235 abgebrochen Es werden lediglich die weiteren Skriptzeilen im Block ab dem Zeitpunkt des Auslösens des ScriptRuntimeError nicht mehr weiterverarbeitet. Die Schleife hingegen wird auch hier weiterverarbeitet.

An den obigen Beispielen sieht man, dass immer nur der Block nicht mehr abgearbeitet wird, aber das restliche Skript unbeeindruckt davon bleibt, also auch nachfolgende oder übergeprdente Blöcke.. Wir können hierzu noch 100 andere Beispiele machen.

So hatte sich das der ursprüngliche Programmierer der ReGaHss vorgestellt.

Nun kommen wir zu den Änderungen, welche ab der ReGaHss-Version R1.00.0388.0109 getätigt wurden

Testskript 4

WriteLine("Start");
WriteLine(dom.BuildLabel());
string lList = "1;2;65535;700;950";
string lEnum;
object lObj;
foreach(lEnum,lList.Split(";"))
{
  WriteLine("------------------------------------------------------------");
  WriteLine(lEnum);
  lObj = dom.GetObject(lEnum);
  WriteLine(lObj.Name());
  WriteLine("Block-Ende");
}
WriteLine("------------------------------------------------------------");
WriteLine("Ende");

Ausgabe mit ReGaHss-Verionen R1.00.0388.0108

Start
R1.00.0388.0108
------------------------------------------------------------
1
DOM
Block-Ende
------------------------------------------------------------
2
Root
Block-Ende
------------------------------------------------------------
65535
null
------------------------------------------------------------
700
AlarmMaps
Block-Ende
------------------------------------------------------------
950
${sysVarPresence}
Block-Ende
------------------------------------------------------------
Ende

Ausgabe mit ReGaHss-Verionen R1.00.0388.0235

Start
R1.00.0388.0235
------------------------------------------------------------
1
DOM
Block-Ende
------------------------------------------------------------
2
Root
Block-Ende
------------------------------------------------------------
65535
null

Auch hier sieht man, dass der ursprüngliche Programmierer (bis R1.00.0388.0108) nur die Abarbeitung des Blockes, eben nur den entsprechenden Schleifendurchlauf als Einzelnen abbricht.

Testskript 5

WriteLine("Start");
WriteLine(dom.BuildLabel());
object lObj;
boolean Try = true;
integer lErrors = 0;
if(Try)
{
  while(lObj.Name())
  {
    WriteLine("While-Block");
  }
  WriteLine("Try-Block");
}
WriteLine("Ende"); 

Ausgabe mit ReGaHss-Verionen R1.00.0388.0108

Start
R1.00.0388.0108
Try-Block
Ende

Ausgabe mit ReGaHss-Verionen R1.00.0388.0235

Start
R1.00.0388.0235
Ende

Auch hier sieht man, dass der ursprüngliche Programmierer (bis R1.00.0388.0108) nur die Abarbeitung des Blockes abbricht.

So ist die ursprüngliche Variante perfekt konsistent, da alle ScriptRuntimeError gleich behandelt werden.

@BadenPower
Copy link
Author

Wenn @BadenPower das wirklich gemeint hat, so erscheint mir das vielmehr ein Methode zu sein um herauszukommen das ein Schleifendurchlauf zum Ende gekommen ist oder nicht und weniger ein try/except like konstrukt zu sein wie das bei andere modernen Programmiersprache so der Fall ist.

Hier einmal ein Error-Handling im Skript der einfachsten Art, um einen ScriptRuntimeError abzufangen:

WriteLine("Start");
WriteLine(dom.BuildLabel());
object lObj;
boolean Try = true;
boolean Finally = true;
boolean Except = false;
if(Try)
{
  Except = true;
  WriteLine("Try-Block");
  lResult =lObj.Name();
  Except = false;
}
if(Except)
{
  WriteLine("Es ist ein Fahler aufgetreten");
}
WriteLine("Ende"); 

Ausgabe:

Start
R1.00.0388.0235
Es ist ein Fahler aufgetreten
Ende

Läßt sich beliebig erweitern, so dass jede Unterebene/Block oder einzelne Anweisung ausgewertet werden kann.

Da das jetzige Verhalten von foreach und while weitere bzw. noch bessere Möglichkeiten zum Error-Handling bieten, wäre ich ja schon geneigt, dass das neue Verhalten beibehlten werden sollte.

Wird das Verhalten jedoch nicht als Bug gesehen, dann resultiert daraus das Problem, dass andere Fälle der Fehlerentstehung mit der "neuen Norm" nicht konsistent wären und diese dann zum Bug würden.

Nun, auch aus diesem Script kann ich nicht wirklich herauslesen warum man es haben wollen würde das die foreach() schleife im Falle eines ScriptruntimeError weiterläuft und seine weiteren Iterationen noch durchführt.

Die gesamten Testskript zur Bug-Findung und Prüfung basieren auf diesem Prinzip.
Nehmen wir zum Beispiel das Testskript für den bereits beseitigten Bug in der .Tan()-Methode:

WriteLine("Start");
WriteLine("ReGaHss-Version: " # dom.BuildLabel());
real lValue;
real lResult;
integer lRunTimeErrors = 0;
integer lOldRunTimeErrors = 0;
string lMethod;
string lType;
integer lEnumValue;

lMethod = '.Tan()';

foreach(lEnumValue,14)
{
  if(lEnumValue == 1) { lValue = "nan".ToFloat(); }
  if(lEnumValue == 2) { lValue = "inf".ToFloat(); }
  if(lEnumValue == 3) { lValue = 1.000000000000001; }
  if(lEnumValue == 4) { lValue = 1.0; }
  if(lEnumValue == 5) { lValue = 0.999999999999999; }
  if(lEnumValue == 6) { lValue = 0.000000000000001; }
  if(lEnumValue == 7) { lValue = 0.0; }
  if(lEnumValue == 8) { lValue = -0.0; }
  if(lEnumValue == 9) { lValue = -0.000000000000001; }
  if(lEnumValue == 10) { lValue = -0.999999999999999; }
  if(lEnumValue == 11) { lValue = -1.0; }
  if(lEnumValue == 12) { lValue = -1.000000000000001; }
  if(lEnumValue == 13) { lValue = "-inf".ToFloat(); }
  if(lEnumValue == 14) { lValue = "-inf".ToFloat(); lValue = lValue * 0.0; }

  WriteLine("--------------------------------------------------");
  lType = lValue.Type();
  lOldRunTimeErrors = lRunTimeErrors;
  if(true)
  {
    lRunTimeErrors = lRunTimeErrors + 1;
    lResult = lValue.Tan();
    WriteLine(lResult);
    WriteLine(lResult.Type());
    lRunTimeErrors = lRunTimeErrors - 1;
    WriteLine("Block " # lType # lMethod # " Variablewert: " # lValue.ToString(15) # " erfolgreich beendet!");
  }
  if(lOldRunTimeErrors <> lRunTimeErrors)
  {
    WriteLine("Block " # lType # lMethod # " Variablewert: " # lValue.ToString(15) # " mit ScriptRuntimeError beendet!");
  }
}

WriteLine("--------------------------------------------------");
if(lRunTimeErrors > 0)
{
  WriteLine("");
  WriteLine("ACHTUNG: Es ist/sind " # lRunTimeErrors.ToString() #  " Laufzeitfehler aufgetreten!");
  WriteLine("");
}
WriteLine("Ende");

Ausgabe einer CCU2 mit aktueller Firmware:

Start
ReGaHss-Version: R1.00.0388.0217
--------------------------------------------------
nan
real
Block real.Tan() Variablewert: nan erfolgreich beendet!
--------------------------------------------------
Block real.Tan() Variablewert: inf mit ScriptRuntimeError beendet!
--------------------------------------------------
1.557408
real
Block real.Tan() Variablewert: 1.000000000000001 erfolgreich beendet!
--------------------------------------------------
1.557408
real
Block real.Tan() Variablewert: 1.000000000000000 erfolgreich beendet!
--------------------------------------------------
1.557408
real
Block real.Tan() Variablewert: 0.999999999999999 erfolgreich beendet!
--------------------------------------------------
0.000000
real
Block real.Tan() Variablewert: 0.000000000000001 erfolgreich beendet!
--------------------------------------------------
0.000000
real
Block real.Tan() Variablewert: 0.000000000000000 erfolgreich beendet!
--------------------------------------------------
-0.000000
real
Block real.Tan() Variablewert: -0.000000000000000 erfolgreich beendet!
--------------------------------------------------
-0.000000
real
Block real.Tan() Variablewert: -0.000000000000001 erfolgreich beendet!
--------------------------------------------------
-1.557408
real
Block real.Tan() Variablewert: -0.999999999999999 erfolgreich beendet!
--------------------------------------------------
-1.557408
real
Block real.Tan() Variablewert: -1.000000000000000 erfolgreich beendet!
--------------------------------------------------
-1.557408
real
Block real.Tan() Variablewert: -1.000000000000001 erfolgreich beendet!
--------------------------------------------------
Block real.Tan() Variablewert: -inf mit ScriptRuntimeError beendet!
--------------------------------------------------
-nan
real
Block real.Tan() Variablewert: -nan erfolgreich beendet!
--------------------------------------------------

ACHTUNG: Es ist/sind 2 Laufzeitfehler aufgetreten!

Ende

@BadenPower
Copy link
Author

BadenPower commented Jan 21, 2024

Da das Beispiel von @HMMike so überhaupt Nichts mit Error-Handling zu tun hat, hier einmal das im Eröffnungspost verwendete Skript, welches durch den Einsatz des "geheimen" Error-Handlings auch mit der neuesten Version der ReGaHss die foreach-Schleife nicht abbricht, sondern bis zum Ende durchläuft und dies trotz ScriptRuntimeError in der Schleife.

WriteLine("Start");
WriteLine(dom.BuildLabel());
string lList = "1;2;65535;700;950";
string lEnum;
object lObj;
foreach(lEnum,lList.Split(";"))
{
  if(true)
  {
    WriteLine("------------------------------------------------------------");
    WriteLine(lEnum);
    lObj = dom.GetObject(lEnum);
    WriteLine(lObj.Name());
    WriteLine("Block-Ende");
  }
}
WriteLine("------------------------------------------------------------");
WriteLine("Ende");

Ausgabe:

Start
R1.00.0388.0235
------------------------------------------------------------
1
DOM
Block-Ende
------------------------------------------------------------
2
Root
Block-Ende
------------------------------------------------------------
65535
null
------------------------------------------------------------
700
AlarmMaps
Block-Ende
------------------------------------------------------------
950
SYS-CCU-Reboot
Block-Ende
------------------------------------------------------------
Ende

Das sind eben die elementaren Grundkenntnisse, welche ich für eine Diskusionsbeteiligung einfach vorraussetze.
Alles nachzulesen in der Skriptdokumentation der HM-Internals.

@BadenPower BadenPower changed the title ReGaHSS: foreach [12/12 BP-14] -> Schleifenabbruch bei ScriptRuntimError in der Schleife ReGaHSS: foreach [12/12 BP-14] -> Schleifenabbruch bei ScriptRuntimeError in der Schleife Jan 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug-report Something isn't working 🏷️ ReGaHss This refs the ReGaHss component ❓ undecided No decision to accept or reject ticket yet
Projects
None yet
Development

No branches or pull requests

4 participants