pat.bat
Goto Top

Welches Konzept zur Fehlerbehandlung bei Programmaufrufen?

Hallo zusammen,

Ich bin gerade am überlegen, wie ich am besten Fehler abfange und das Skript "sicher" beende.

Dabei tut das Skript folgendes:

In einem externen Programm erstelle ich eine Reihe von Jobs, diese werden normalerweise direkt in der Windows Aufgabenplanung angelegt. Nun soll mein Skript aber auch weitere Aufgaben unternehmen und den ganzen Verlauf protokollieren und bei Fehlern diese ins Log schreiben und ggf. per E-Mail an die Systemadministratoren schicken.

In meinem Skript werden nun die Batches ein nach dem anderen aufgerufen, davor und danach wird jeweils ein Logeintrag geschrieben (mit Datum, Uhrzeit, usw.)

Wenn der Batch nun das externe Programm mit der Anweisung aufruft und bestimmte Aufgaben erledigen soll und dabei auf einen Fehler trifft, wie kann ich dies am besten abfangen?
den Batch interessiert es soweit nicht ob das Programm mit einem Fehler beendet oder nicht (Keine Fehlermeldung im Programm selber, es schließt einfach).

Das Programm erzeugt nun aber selber logs, in denen unter Umständen ein Fehlercode gespeichert wird, siehe Beispiel:

15.07.2019 10:45:37	0-BEG0001	Start des Jobs
15.07.2019 10:45:37	0-PAB0010	----- BEGINN JOBPARAMETER -----
15.07.2019 10:45:37	0-PAR0011	Jobname=Prüflauf EV Umbuchung
15.07.2019 10:45:37	0-PAR0011	BezeichnungDesPrueflaufes=Prüflauf EV Umbuchung
15.07.2019 10:45:37	0-PAR0011	AZBis=
15.07.2019 10:45:37	0-PAR0011	AZVon=
15.07.2019 10:45:37	0-PAR0011	Einzel=J
15.07.2019 10:45:37	0-PAR0011	Global=J
15.07.2019 10:45:37	0-PAR0011	Manuelle=J
15.07.2019 10:45:37	0-PAR0011	NichtManuelle=J
15.07.2019 10:45:37	0-PAR0011	nurUmbuchungen=J
15.07.2019 10:45:37	0-PAR0011	ElektronischePrüfaufträge=0
15.07.2019 10:45:37	0-PAR0011	Stichtag=01.02.2019
15.07.2019 10:45:37	0-PAR0011	ZusaetzlicheTage=28
15.07.2019 10:45:37	0-PAR0011	Mandanten=N
15.07.2019 10:45:37	0-PAR0011	WizardTyp=26
15.07.2019 10:45:37	0-PAR0011	Modus=2
15.07.2019 10:45:37	0-PAE0012	----- ENDE JOBPARAMETER -----
15.07.2019 10:45:40	0-MSG0199	NeuerPrüflauf: Prüflauf EV Umbuchung
15.07.2019 10:45:40	0-MSG0199	Anzahl durchgeführter Buchungen: 0
15.07.2019 10:45:40	2-NTD1053	Prüflauf hat keine Buchungen.
15.07.2019 10:45:40	0-INB0100	----- BEGINN JOB RESULTAT -----
15.07.2019 10:45:40	0-INF0107	Anzahl Fälle: 0
15.07.2019 10:45:40	0-INF0108	Durchschn. Zeit pro Fall: Es konnte keine Gesamtdauer ermittelt werden.
15.07.2019 10:45:40	0-INF0109	Summe Bearbeitungszeit: Es konnte keine Gesamtdauer ermittelt werden.
15.07.2019 10:45:40	0-INE0101	----- ENDE JOB RESULTAT -----
15.07.2019 10:45:40	0-MSG0199	ERRLEVEL=2
15.07.2019 10:45:40	0-INF0110	ERRORLEVEL=2
15.07.2019 10:45:40	0-END0002	Ende des Jobs

Wie man sehen kann, wird hier der der Errorcode 2-.... geworfen mit der Nachricht "Prüflauf hat keine Buchungen."

und unten dann nochmal ERRLEVEL=2.

Daraus gehen für mich nur 2 Optionen hervor.

1. Etwa es gibt eine Möglichkeit den Error abzufangen, wenn das Programm noch läuft, bzw das ich den Error "lesen" kann.

2. Oder ich muss danach im Grunde in den Log Ordner schauen, die .log Datei öffnen und nach dem Inhalt ERRLEVEL prüfen. Falls dieser nicht 0 ist, dann nochmal nach einem Text 2-.... mit Beschreibung und gebe das dann in meinem Log weiter und ggf. in einer E-Mail an die Admins.

Sobald ich einen Error Code erhalte würde ich diesen dann in einem Try Catch ErrorHandling in meinem Skript verarbeiten und das Skript dementsprechend beenden bzw Aufräumen lassen.

Beim Skript handelt es sich um ein PowerShell Skript.

Content-Key: 473539

Url: https://administrator.de/contentid/473539

Printed on: April 19, 2024 at 00:04 o'clock

Member: chiefteddy
chiefteddy Jul 15, 2019 at 09:26:16 (UTC)
Goto Top
Hallo,

die Frage lautet doch: Liefert das externe Programm beim Beenden einen auswertbaren Error-Code an das aufrufende Scribt zurück oder nicht?

Das kannst doch nur du testen!

Jürgen
Member: Pat.bat
Pat.bat Jul 15, 2019 at 11:37:02 (UTC)
Goto Top
ok also müsste ich den Error-Code in der Batch Datei abrufen, momentan besteht diese nur aus einer Zeile, dem Programmaufruf samt Parameter.

"c:\Program Files (x86)\Testprogramm.exe" -JOB 123400000000028

Dann sollte ich vermutlich den Programmaufruf gleich in PowerShell durchführen und dann z.B. via

catch{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
write-log $error.Exception.GetType().FullName
}

abfangen oder gibt es einen anderen Weg einen Fehler abzufangen?

Ich bin mir nicht sicher wie ein Programm einen Fehlercode nach extern übergibt, bzw. ob das bei uns verwendete Programm dies überhaupt tut.
Member: Pat.bat
Pat.bat Jul 15, 2019 at 12:22:08 (UTC)
Goto Top
OK,

nachdem ich nun folgendes ausprobiert habe. Bekomme ich zumindest den Errorcode wie er auch in der Log Datei erscheint, 2.

Dazu habe auf die schnelle ein Codeschnippsel aus meiner google Suche verwendet:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "c:\Program Files (x86)\Testprogramm.exe"  
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "-JOB 123400000000023"  
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
Write-Host "stdout: $stdout"  
Write-Host "stderr: $stderr"  
Write-Host "exit code: " + $p.ExitCode  

als Output bekomme ich folgendes:

stdout:
stderr:
exit code: + 2

Der Code ist zwar nicht viel, aber damit kann ich zumindest schonmal arbeiten und mir eine Switch Anweisung bauen, wo ich die Codes hinterlege.

Ideal wäre es gewesen, wenn man gleich den Fehlertext noch mit bekommt und den kompletten Fehlercode. Aber das scheint in diesem Falle wohl nicht möglich zu sein.
Member: chiefteddy
Solution chiefteddy Jul 15, 2019 at 12:35:25 (UTC)
Goto Top
Ideal wäre es gewesen, wenn man gleich den Fehlertext noch mit bekommt und den kompletten Fehlercode.

Hallo,

normalerweise liefert der Hersteller eines Programms in seiner Dokumentation eine Liste der Fehlercodes und ihrer Bedeutung.

Ein Programm wird üblicher weise immer nur den Fehlercode zurückgeben.

Notfalls mußt du Fehler provozieren und Code + Meldung selber ermitteln.

Jürgen
Member: Pat.bat
Pat.bat Jul 15, 2019 at 14:22:46 (UTC)
Goto Top
OK ich habs dann jetzt so gelöst:

in meiner StartBatch.ps1 gebe ich den ErrorCode zurück.

Im Hauptskript liegt dann die Funktion

# Funktion zum Starten von Batches
#-------------------------------------------------------------------
function StartBatch($JobID)
{
    $ErrorCode = .\StartBatch.ps1 -JobID $JobID
    If ($ErrorCode -ne 0)
    {
        $ErrorCode = "F$ErrorCode"  
        Log-Writer -TextID $ErrorCode -Loglevel 3 -LogAction P2
        Exit 0
    }
}

bereit. Sobald ich auf einen Fehler stoße, wird eine entsprechende Nachricht ins Log gespeichert (Diese wird durch 2 weitere Skripte generiert).
Die Fehlertexte hinterlege ich dann per Hand im Skript, da es keine wirklich gute Doku für Fehlertexte des Programmes gibt.

Vielen Dank für die Hilfe Jürgen.