Guten Morgen Rudi,
habe gestern zufällig festgestellt, dass die Funktion perlSyntaxCheck bei einem festgestellten Fehler zwar eine entsprechende Meldung ins Log schreibt, aber kein ret zurückgegeben wird.
Beispielaufruf:
$aVal = $_[3];
my %specials = (
"%CONTENT" => "1",
"%FAC" => "1",
"%SEV" => "1"
);
my $err = perlSyntaxCheck($aVal, %specials);
return $err if($err);
Ich konnte in $aVal eine x-beliebige fehlerhafte Perlsyntax checken lassen, ohne dass $err gesetzt wird.
Als Ursache habe ich eine m.M.nach ungünstige Rückgabebehandlung von "$@" in der sub AnalyzePerlCommand festgestellt.
Zum fixen habe die Zeilen 1113-1114 in fhem.pl:
Log 1, "ERROR evaluating $cmd: $@" if($@);
$ret = $@ if($@);
ersetzt durch:
if($@) {
$ret = $@;
Log 1, "ERROR evaluating $cmd: $ret";
}
Damit klappt es nun wie gewünscht auch mit dem gesetzten $err und negative Seiteneffekte habe ich auch nicht festgestellt.
Prüfe bitte mal den Change von deiner Seite.
Diff ist anbei.
viele Grüße
Heiko
Kannst du mir bitte einen konreten Beispiel nennen?
Folgendes schaut fuer mich ok aus:fhem> { perlSyntaxCheck("{ bla bla bla }", ()) }
Bareword "bla" not allowed while "strict subs" in use at (eval 20) line 1.
Achtung: perlSyntaxCheck prueft nur Code, was mit { anfaengt.
Ja, zum Beispiel folgendes. Das komplette Codestückchen ist aus der Attr_X und prüft den eingefügten Code im Attribut parseFn
if ($cmd eq "set" && $aName =~ /parseFn/) {
$_[3] = "{$aVal}" if($aVal !~ m/^\{.*\}$/s);
$aVal = $_[3];
my %specials = (
"%DATA" => "1",
"%PRIVAL" => "1",
"%TS" => "1",
"%DATE" => "1",
"%TIME" => "1",
%HOST" => "1",
"%ID" => "1",
"%PID" => "1",
"%MID" => "1",
"%CONT" => "1",
"%FAC" => "1",
"%SEV" => "1"
);
my $err = perlSyntaxCheck($aVal, %specials);
return $err if($err);
}
Wenn ich nun das im Attribut {$st = 1} setze, wird dies geprüft und ordnungsgemäß im Log
2018.08.04 15:56:27.527 1: ERROR evaluating my $SEV='1';my $HOST='1';my $DATA='1';my $CONT='1';my $DATE='1';my $PID='1';my $MID='1';my $ID='1';my $TIME='1';my $PRIVAL='1';my $FAC='1';my $TS='1';{return undef; {$st = 1}}: Global symbol "$st" requires explicit package name (did you forget to declare "my $st"?) at (eval 2248) line 1.
ausgegeben. Allerdings wird kein "$@"-Wert weitergegeben und demzufolge auch $err nicht gesetzt. Es kommt kein Fehlerpopup und das Attribut wird gesetzt obwohl fehlerhaft.
Mit der von mir gemachten kleinen Änderung klappt das . Es kommt neben dem Logeintrag ebenso das Popup für die fehlerhafte Codeprüfung.
Im Prinzip kann man eintippen was man will , der Logeintrag kommt , das Popup nicht.
ZitatWenn ich nun das im Attribut {$st = 1} setze ... kommt kein Fehlerpopup und das Attribut wird gesetzt obwohl fehlerhaft.
Ich weiss nicht, wie du das Attribut pruefst. Fuer
attr n devStateIcon { $st = 1 }
kriege ich ueberall eine passende Fehlermeldung, ich habe telnet, FHEMWEB Befehlseingabe und attr-Feld setzen in der Detailansicht probiert.
Nachtrag: das Attribut wird natuerlich nicht gesetzt, und je nach Stelle der Eingabe kriege ich den Fehler im Dialog (FHEMWEB attr Zeile oder Raw definition) oder anderweitig "passend" angezeigt.
Ich gebe den Wert einfach im FHEMWEB im Attributfeld ein und es geht durch.
Jetzt habe ich
attr SyslogServer_IETF parseFn {$st = 1}
in der FHEMWEB Befehlszeile abgesetzt. Geht auch ohne Fehlermeldung durch und das Attr wird gesetzt.
Hier mal ein List von dem Device:
Internals:
FD 38
INTERFACE global
LOGFORMAT IETF
MODEL Collector
MYHOST fhemtest.myds.me
NAME SyslogServer_IETF
NR 541
NTFY_ORDER 50-SyslogServer_IETF
PORT 1514
PROTOCOL udp
SEQNO 12783
STATE active : 152
TYPE Log2Syslog
VERSION 4.4.0
HELPER:
LTIME 1533395847
OLDSEQNO 12703
OLDSTATE active
SSLALGO n.a.
SSLVER n.a.
Helper:
DBLOG:
Transfered_logs_per_minute:
LogDB1:
TIME 1533395847.63228
VALUE 152
fhem.myds.me:
LogDB1:
TIME 1533395881.146
VALUE FAC: syslog _ESC__ESC_ SEV: Notice _ESC__ESC_ ID: Prod_event _ESC__ESC_ CONT: sysmon ram: Total: 1758.07 MB, Used: 400.30 MB, 22.77 %, Free: 702.81 MB
state:
LogDB1:
TIME 1533390888.52508
VALUE active
READINGS:
2018-08-04 15:54:41 SSL_Algorithm n.a.
2018-08-04 15:54:41 SSL_Version n.a.
2018-08-04 17:17:27 Transfered_logs_per_minute 152
2018-08-04 17:18:01 state active
Attributes:
disable 0
includeFields CONTENT,HOST,MID,IDENT
parseFn {$st = 1}
parseProfile IETF
port 1514
rateCalcRerun 80
room DbLog
stateFormat state : Transfered_logs_per_minute
verbose 3
Kann es sein dass das Verhalten von eval bzw. $@ abhängig von Perl-Version / BS ist ?
Mir ist es schon öfter aufgefallen, dass $@ "flüchtig" ist und nur quasi bis zum nächsten Befehl verfügbar ist. Deswegen
setze ich immer zuerst $var = $@ und mache dann alle weiteren Auswertungen mit $var. Das Verfahren ist dann kompatibel.
Was besseres fällt mir grad nicht ein. :(
Übrigens, der Befehl
attr SyslogServer_IETF devStateIcon { $st = 1 }
läuft bei mir ebenfalls fehlerfrei durch und das Attr wird gesetzt:
Internals:
FD 38
INTERFACE global
LOGFORMAT IETF
MODEL Collector
MYHOST fhemtest.myds.me
NAME SyslogServer_IETF
NR 541
NTFY_ORDER 50-SyslogServer_IETF
PORT 1514
PROTOCOL udp
SEQNO 16682
STATE active : 163
TYPE Log2Syslog
VERSION 4.4.0
HELPER:
LTIME 1533397448
OLDSEQNO 16676
OLDSTATE active
SSLALGO n.a.
SSLVER n.a.
Helper:
DBLOG:
Transfered_logs_per_minute:
LogDB1:
TIME 1533397448.49081
VALUE 163
fhem.myds.me:
LogDB1:
TIME 1533397457.07408
VALUE FAC: syslog _ESC__ESC_ SEV: Notice _ESC__ESC_ ID: Prod_event _ESC__ESC_ CONT: eg.kueche.wandthermostat.Climate measured-temp: 27.7
state:
LogDB1:
TIME 1533390888.52508
VALUE active
READINGS:
2018-08-04 15:54:41 SSL_Algorithm n.a.
2018-08-04 15:54:41 SSL_Version n.a.
2018-08-04 17:44:08 Transfered_logs_per_minute 163
2018-08-04 17:44:17 state active
Attributes:
devStateIcon { $st = 1 }
disable 0
includeFields CONTENT,HOST,MID,IDENT
parseFn {$st = 1}
parseProfile IETF
port 1514
rateCalcRerun 80
room DbLog
stateFormat state : Transfered_logs_per_minute
verbose 3
Ha :)
Auf meinem Debian 9 kommt es zu der beschriebenen Problematik.
Auf einem anderen System mit Debian 8 klappt die Prüfung so wie bei dir !
Wobei auf beiden System Perl 5.24.1 drauf ist.
Amazing ...
- es werden nicht beliebige Attribute mit perlSytaxCheck geprueft. In fhem.pl passiert das fuer devStateIcon und stateFormat, sonst muss sich das Modul explizit darum kuemmern.
- geprueft wird nur, falls das Attribut perlSyntaxCheck gesetzt ist. Die Voreinstellung ist 1 fuer featurelevel > 5.7, sonst 0
- die perl Version duerfte dabei egal sein.
Zitatgeprueft wird nur, falls das Attribut perlSyntaxCheck gesetzt ist. Die Voreinstellung ist 1 fuer featurelevel > 5.7, sonst 0
Ja, den Zusammenhang kenne ich.
Wie gesagt "attr SyslogServer_IETF devStateIcon { $st = 1 }" auf dem Debian 9 läuft fehlerfrei durch, das gleich auf dem Debian 8 bringt den erwartungsgemäßen Fehler.
Auf beiden System aktuelle fhem.pl und kein featurelevel gesetzt.
Und wenn ich auf dem Debian 9 den von mir beschriebene Patch einsetzte und sonst NICHTS ändere klappte die Prüfung auch auf diesem System erwartungsgemäß
Das bedeutet, dass auf der Debian 9 Installation die Funktion Log ein eval durchgefuehrt hat, waere interessant zu wissen wo.
Ich habe dein Patch eingebaut, spart ja auch eine Abfrage.
Danke Rudi :)
Grüsse und ein schönes WE.
Heiko