Ansicht
Dokumentation

ABENCLASS_EXCEPTION_GUIDL - CLASS EXCEPTION GUIDL

ABENCLASS_EXCEPTION_GUIDL - CLASS EXCEPTION GUIDL

ROGBILLS - Synchronize billing plans   SUBST_MERGE_LIST - merge external lists to one complete list with #if... logic for R3up  
Diese Dokumentation steht unter dem Copyright der SAP AG.
SAP E-Book

Klassische und klassenbasierte Ausnahmen

Aus Gründen der Abwärtskompatibilität gibt es in ABAP zwei Möglichkeiten, behandelbare Ausnahmen selbst zu definieren:

Diese Ausnahmen können nur in den Schnittstellen von Methoden oder Funktionsbausteinen mit EXCEPTIONS deklariert und innerhalb einer solchen Prozedur mit den Anweisungen RAISE oder MESSAGE RAISING ausgelöst werden. Der Aufrufer der Prozedur kann mit dem Zusatz EXCEPTIONS der Anweisungen meth( ... ) bzw. CALL FUNCTION den Ausnahmen, die er behandeln möchte, Rückgabewerte für das Systemfeld sy-subrc zuordnen und dieses nach dem Aufruf auswerten.
Diese Ausnahmen werden durch Ausnahmeklassen definiert, von denen im Auslösefall bei Bedarf (wenn ein Behandler den Zusatz INTO bei CATCH verwendet) ein Ausnahmeobjekt erzeugt wird. Eine klassenbasierte Ausnahme kann den aktuellen Kontext entweder abbrechen oder aber ein Wiederaufsetzen erlauben. Das Auslösen erfolgt mit der Anweisung RAISE EXCEPTION, die Behandlung über CATCH in einer TRY-Kontrollstruktur. Klassenbasierte Ausnahmen können in beliebigen Prozeduren ausgelöst und durch beliebige Prozeduren weiterpropagiert werden.

Die Koexistenz der beiden Ausnahmekonzepte ist wie folgt geregelt:

  • Es können keine klassischen und klassenbasierten Ausnahmen gemeinsam in der Schnittstelle einer Prozedur deklariert werden, und innerhalb eines Verarbeitungsblocks können entweder nur klassische oder nur klassenbasierte Ausnahmen ausgelöst werden.
  • Aus Gründen der Interoperabilität dürfen innerhalb eines Verarbeitungsblocks sowohl klassenbasierte Ausnahmen behandelt als auch die Rückgabewerte von Funktionsbausteinen und Methoden mit klassischen Ausnahmen ausgewertet werden.

Klassenbasierte Ausnahmen verwenden

Lösen Sie in neuen Prozeduren nur noch klassenbasierte Ausnahmen aus, soweit ein Verzicht auf klassische Ausnahmen technisch möglich ist.

Die selbst definierten klassischen Ausnahmen sind kaum mehr als Rückgabewerte. Wird in einer Prozedur mit der Anweisung RAISE eine klassische Ausnahme ausgelöst, ist nach der Rückkehr zum Aufrufer das Systemfeld sy-subrc gemäß der ausgelösten Ausnahme gesetzt. Der Aufrufer muss durch die Abfrage von sy-subrc stets selbst überprüfen, ob eine Ausnahme aufgetreten ist und gegebenenfalls auch auf diese selbst reagieren, sei es durch geeignete Behandlung oder explizites Weiterleiten an den eigenen Aufrufer (durch Auslösen einer eigenen, gleichbedeutenden Ausnahme). Dies trägt nicht zur Übersichtlichkeit des Programms bei.

Das Auftreten klassenbasierter Ausnahmen bewirkt hingegen eine Änderung des Programmflusses. Sie können entweder an Ort und Stelle behandelt oder entlang der Aufrufhierarchie nach oben propagiert werden. Auf diese Weise muss nicht jede Prozedur (Methode) jede mögliche Ausnahmesituation selbst berücksichtigen. Dies unterstützt die Trennung der Belange innerhalb einer Anwendung. Dadurch, dass die Ausnahme durch ein Objekt einer Ausnahmeklasse repräsentiert werden kann, kann dieses Ausnahmeobjekt zusätzliche Informationen zur Ausnahmesituation aufnehmen und zum Behandler transportieren. Dieses kann im Gegensatz zu klassischen Ausnahmen auch spezifische Ausnahmetexte umfassen.

Standardmäßig beendet das Auslösen einer Ausnahme den gesamten aktuellen Kontext auch dann, wenn die Ausnahme behandelt wird. Es kann aber Situationen geben, in denen ein einzelner Fehler es nicht rechtfertigt, einen gesamten Service, wie zum Beispiel eine Massendatenverarbeitung, abzubrechen. Für diese Fälle können klassenbasierte Ausnahmen wiederaufsetzbar (RESUMABLE) ausgelöst und propagiert werden. Ein Behandler kann entscheiden, ob ein Service vollständig abgebrochen oder - beispielsweise nach dem Schreiben eines entsprechenden Protokolleintrags - mit der Anweisung RESUME wieder aufgenommen wird.

Klassenbasierte Ausnahmen lösen die klassischen Ausnahmen für neuen Code vollständig ab (Ausnahmen von dieser Regel gibt es natürlich) und erweitern sie um die Wiederaufsetzbarkeit. Obwohl klassische Ausnahmen auf Auslöserseite damit technisch gesehen vollständig obsolet sind, ist für Bestandscode aber dennoch Folgendes zu beachten: Auch wenn man hier die Auslöserseite selbst unter Kontrolle hat, kann man diese Prozeduren im Allgemeinen nicht einfach auf klassenbasierte Ausnahmen umstellen, weil dann sämtliche Verwendungsstellen angepasst werden müssten.

Beim Aufruf bestehender Prozeduren, die klassische Ausnahmen verwenden, müssen diese natürlich auch in neuem Code weiterhin behandelt werden. In diesem Fall ist es empfehlenswert, die klassischen Ausnahmen mit RAISE EXCEPTION auf gleichbedeutende klassenbasierte Ausnahmen abzubilden. Auf diese Weise wird nach außen hin eine einheitliche klassenbasierte Fehlerbehandlung erreicht. Die Ausnahmesituation kann dann auch an höhere Aufrufschichten weitergeleitet werden, ohne dass jede einzelne Schicht explizit auf diese Situation reagieren muss.

Ausnahme

Da klassenbasierte Ausnahmen in remotefähigen Funktionsbausteinen (RFM) noch nicht unterstützt werden, müssen beim Remote Function Call (RFC) weiterhin klassische Ausnahmen eingesetzt und behandelt werden.

Folgender Quelltext zeigt die Deklaration und das Auslösen einer klassischen Ausnahme in einer Methode sowie deren Behandlung durch die Auswertung von sy-subrc nach einem Aufruf der Methode. Diese Vorgehensweise verstößt gegen obige Regel.

CLASS application DEFINITION.
  PUBLIC SECTION.
    METHODS do_something
    EXCEPTIONS application_error.
ENDCLASS.

CLASS application IMPLEMENTATION.
  METHOD do_something.
    ...
    RAISE application_error.
    ...
  ENDMETHOD.
ENDCLASS.

...

... oref TYPE REF TO application.

...

oref->do_something(
  EXCEPTIONS application_error = 4 ).
IF sy-subrc <> 0.
  ...
ENDIF.

Folgender Quelltext zeigt die Definition einer Ausnahmeklasse, ihre Deklaration und das Auslösen in einer Methode sowie deren Behandlung durch CATCH nach einem Aufruf der Methode in einem TRY-Block.

CLASS cx_application_error DEFINITION
  INHERITING FROM cx_static_check.
ENDCLASS.

CLASS application DEFINITION.
  PUBLIC SECTION.
    METHODS do_something
      RAISING cx_application_error.
ENDCLASS.

CLASS application IMPLEMENTATION.
  METHOD do_something.
    ...
    RAISE EXCEPTION TYPE cx_application_error.
    ...
  ENDMETHOD.
ENDCLASS.

...

... oref TYPE REF TO application.

...

TRY.
    oref->do_something( ).
    CATCH cx_application_error.
      ...
ENDTRY.

In diesem einfachen Beispiel ist der große Vorteil klassenbasierter Ausnahmen gegenüber klassischen Ausnahmen nicht unbedingt offensichtlich. Er zeigt sich aber deutlich bei geschachtelten Prozeduraufrufen und der Behandlung von Ausnahmen, die in weiter entfernten Aufrufebenen ausgelöst wurden.






General Material Data   PERFORM Short Reference  
Diese Dokumentation steht unter dem Copyright der SAP AG.

Length: 9242 Date: 20240523 Time: 175355     sap01-206 ( 158 ms )