Try-Catch-Codeblöcke

Nach der Implementierung des throw() -Befehls und der Einführung des Try(Expression)-Schlüsselworts freuen wir uns, die nächste Entwicklung im Fehlerbehandlungssystem von 4D vorstellen zu können: die Einführung von Try-Catch-Codeblöcken!

Ab 4D 20 R5 können Anwender ihre Fähigkeiten zur Fehlerbehandlung verbessern, indem sie die Leistungsfähigkeit der neuen Schlüsselwörter Try, Catch und End try nutzen.
Um die praktische Anwendung dieser neuen Schlüsselwörter zu veranschaulichen, wollen wir ein Beispiel für die Erstellung von Rechnungen mit Rechnungszeilen untersuchen. An diesem Beispiel werden die unmittelbaren Vorteile dieser neuen Schlüsselwörter deutlich:

Function createInvoice($customer: cs.customerEntity; $items: Collection; $invoiceRef: Text) : cs.invoiceEntity
var $newInvoice : cs.invoiceEntity
var $newInvoiceLine : cs.invoiceLineEntity
var $item : Object

ds .startTransaction()
Try
$newInvoice :=This.new()
$newInvoice .customer:=$customer
$newInvoice .invoiceRef:=$invoiceRef
For each ($item; $items)
$newInvoiceLine :=ds.invoiceLine.new()
$newInvoiceLine .item:=$item.item
$newInvoiceLine .amount:=$item.amount
$newInvoiceLine .invoice Catch invoiceRef $invoiceRef
items:=$newInvoice
$newInvoiceLine .save()
End for each
$newInvoice .save()
ds .validateTransaction()

ds .cancelTransaction()
$newInvoice :=Null
ds .logErrors({\
message : "Invoice creation failed";\
errors : Last errors;\
customer : $customer.ID;\
xml-ph-0033@deep $items\
})
End try
return $newInvoice

Bei der Erstellung dieses Beispiels geht es dem Entwickler nicht um die genaue Stelle, an der ein Fehler auftritt. Er möchte lediglich den Fehler aufzeichnen und sicherstellen, dass er keine ungültigen Daten erstellt hat.
Die Funktion erhält die Kundenentität, die Artikelsammlung und den Rechnungsbezug als Parameter.
Um die Datenintegrität während des Erstellungsprozesses zu schützen, beginnt eine Transaktion am Anfang.
Der gesamte Erstellungscode ist in einem Try-Code-Block geschützt.
Wenn die Rechnung und die Rechnungszeilen ohne Fehler erstellt wurden, wird die Transaktion am Ende des Try-Codeblocks validiert.
Tritt jedoch ein Fehler auf, wird der Catch-Codeblock an der Stelle ausgeführt, an der er im Try-Codeblock aufgetreten sein könnte. Im Catch-Codeblock wird die Transaktion abgebrochen, und der Fehler wird von einer benutzerdefinierten Funktion protokolliert.

 

Try-Catch-Codeblöcke im Detail

Um die Ausführung eines Codeblocks vor der Anzeige eines 4D Fehlerdialogs zu schützen, können Sie ihn nun mit den Schlüsselwörtern Try und End try arbeiten.
Die Fehlerbehandlung ist nicht zwingend erforderlich, aber besser! So können Sie nun ein Catch-Schlüsselwort vor dem End try-Schlüsselwort einfügen und den Code für die Fehlerbehandlung in mehreren Zeilen zwischen den Schlüsselwörtern Catch und End try schreiben. Diese Praxis ist in anderen Sprachen üblich und macht lange Methoden/Funktionen einfacher zu lesen!

Wenn bei der Ausführung des Try-Codeblocks kein Fehler auftritt, überspringt der Code den Catch-Codeblock, falls vorhanden, und fährt nach dem Schlüsselwort End try fort.
Wenn jedoch ein Fehler durch eine beliebige Codezeile im Try-Codeblock ausgelöst wird, wird der Catch-Codeblock übersprungen:

  1. Falls vorhanden, wird der aktuelle Error-Handler nicht aufgerufen.
  2. Das 4D Fehlerdialogfeld wird nicht angezeigt.
  3. Der Fehler wird dem aktuellen Errorstack hinzugefügt.
  4. Die Codeausführung wechselt sofort in den Catch-Codeblock. Fehlt das Catch-Schlüsselwort, wird die Codeausführung unmittelbar nach dem entsprechenden End try-Schlüsselwort übersprungen.

 

Beachten Sie, dass, wenn für den aktuellen Ausführungskontext kein Fehlerhandler definiert ist und während der Ausführung des Catch-Codeblocks ein Fehler auftritt, das 4D-Fehlerdialogfeld angezeigt wird. Sie können aber auch Try(Expression) oder verschachtelte Try-Catch-Codeblöcke verwenden, um die Anzeige des 4D-Fehlerdialogfelds zu vermeiden!

 

Über den ERRORSTACK

Bevor die erste Zeile des Try-Code-Blocks ausgeführt wird, wird der aktuelle Fehler-Stack geleert. Dieses Verhalten ist in den meisten Fällen von Vorteil, da es nicht notwendig ist, den Fehlerstapel vor und nach der Ausführung zu vergleichen, um neue Fehler zu erkennen.
Wenn Sie also einen Try-Catch-Codeblock in einen Catch-Codeblock einfügen und den gesamten Errorstack abrufen wollen, vergessen Sie nicht, ihn vorher in einer Sammlung zu speichern, wie in diesem Beispiel:

var $errors : Collection
Try
throw (123; "Erster Fehler")
Catch
$errors .push(Last errors)
Try
throw (456; "Zweiter Fehler")
Catch
$errors .push(Last errors)
// $errors collection contains the two previous errors
End try
End try

 

Vermischung mit globaler Fehlerbehandlung

Die Fehlerbehandlung mit dem ON ERR CALL Befehl ist auch heute noch relevant. Sie kann effektiv mit den Codeblöcken Try(Expression) und Try-Catch verwendet werden. Denken Sie nur an die Priorität der Fehlerbehandlung:

  1. Try(Expression). Dies ist die genaueste Methode, da sie es Ihnen ermöglicht, in einer einzigen Zeile auf Fehler zu prüfen.
  2. Try-Catch-Codeblöcke. Dies ist die beste Methode, wenn Sie eine zeilenweise Fehlerprüfung für irrelevant halten.
  3. ON ERR CALL Befehl mit der Standardoption ek local, um nicht verwaltete Fehler bei der bevorstehenden Codeausführung im aktuellen Prozess/Worker zu erkennen.
  4. ON ERR CALL Befehl mit den Optionen ek global und ek errors from components, um Fehler überall dort zu erkennen, wo kein Fehlerbehandlungssystem installiert oder kodiert wurde.

 

Vergessen Sie nicht, dass die Hauptvorteile der Codierung der Fehlerbehandlung mit Try(Expression) oder Try-Catch Codeblöcken folgende sind:

  • die Fehlerbehandlung so nah wie möglich am fehlerverursachenden Code zu platzieren
  • Verwendung lokaler Variablen im Code der Fehlerbehandlung

 

Sie haben nun alle Karten in der Hand, um Fehler so zu behandeln, wie Sie es wünschen, und Ihren Code sicherer zu machen!

Wir sind bestrebt, unseren Nutzern die bestmögliche Erfahrung zu bieten, und wir ermutigen Sie, Ihre Gedanken und Kommentare im 4D Forum zu teilen. Ihr Feedback hilft uns, Ihre Bedürfnisse zu verstehen und unsere Produkte und Dienstleistungen kontinuierlich zu verbessern.
Viel Spaß beim Programmieren!

Avatar
- Product Owner - Damien Fuzeau ist seit Februar 2019 Mitglied des 4D Produktteams. Als Product Owner ist er für das Schreiben von User Stories zuständig, die er dann in funktionale Spezifikationen umsetzt. Zu seinen Aufgaben gehört es auch, dafür zu sorgen, dass die gelieferten Funktionsimplementierungen den Anforderungen der Kunden entsprechen. Damien hat an der Universität von Nantes einen Abschluss in Softwaretechnik gemacht. Er verbrachte mehr als 23 Jahre in seinem früheren Unternehmen, zunächst als Entwickler (er entdeckte 4D im Jahr 1997) und später als technischer Leiter und Softwarearchitekt. Dieses Unternehmen ist ein 4D OEM Partner und hat 4D basierte Geschäftssoftware für Tausende von Usern auf Hunderten von Servern eingesetzt. Damien ist also mit der Entwicklung und dem Einsatz von 4D in einem mehrsprachigen Kontext vertraut.