SAP ABAP - 異常處理



異常是在程式執行過程中出現的錯誤。當發生異常時,程式的正常流程會被中斷,程式應用會異常終止,這是不推薦的,因此這些異常需要被處理。

異常提供了一種將控制權從程式的一個部分轉移到另一個部分的方法。ABAP 異常處理建立在三個關鍵字之上 - RAISE,TRY,CATCH 和 CLEANUP。假設一個塊會引發異常,一個方法使用 TRY 和 CATCH 關鍵字的組合捕獲異常。TRY - CATCH 塊放置在可能生成異常的程式碼周圍。以下是使用 TRY – CATCH 的語法:

TRY.      
Try Block <Code that raises an exception> 
  
CATCH  
Catch Block <exception handler M>  
. . . 
. . . 
. . . 
CATCH  
Catch Block <exception handler R>
   
CLEANUP. 
   Cleanup block <to restore consistent state>
 
ENDTRY.

RAISE - 引發異常以指示某些異常情況已發生。通常,異常處理程式會嘗試修復錯誤或找到替代解決方案。

TRY - TRY 塊包含需要處理異常的應用程式程式碼。此語句塊按順序處理。它可以包含進一步的控制結構以及過程或其他 ABAP 程式的呼叫。它後面跟著一個或多個 catch 塊。

CATCH - 程式在程式中想要處理問題的地方使用異常處理程式捕獲異常。CATCH 關鍵字表示捕獲異常。

CLEANUP - 每當 TRY 塊中發生未被同一 TRY - ENDTRY 結構的處理程式捕獲的異常時,都會執行 CLEANUP 塊中的語句。在 CLEANUP 子句中,系統可以將物件恢復到一致狀態或釋放外部資源。也就是說,可以為 TRY 塊的上下文執行清理工作。

引發異常

可以在方法、函式模組、子程式等中的任何位置引發異常。異常可以引發的方式有兩種:

  • 由 ABAP 執行時系統引發的異常。

    例如 Y = 1 / 0。這將導致型別為 CX_SY_ZERODIVIDE 的執行時錯誤。

  • 由程式設計師引發的異常。

    同時引發並建立異常物件。在第一種情況下,使用已存在的異常物件引發異常。語法如下:RAISE EXCEPTION exep。

捕獲異常

處理程式用於捕獲異常。

讓我們看一下程式碼片段:

DATA: result TYPE P LENGTH 8 DECIMALS 2, 
exref TYPE REF TO CX_ROOT, 
msgtxt TYPE STRING. 
PARAMETERS: Num1 TYPE I, Num2 TYPE I. 
TRY. 
result = Num1 / Num2. 
CATCH CX_SY_ZERODIVIDE INTO exref. 
msgtxt = exref→GET_TEXT( ). 

CATCH CX_SY_CONVERSION_NO_NUMBER INTO exref. 
msgtxt = exref→GET_TEXT( ).

在上面的程式碼片段中,我們嘗試將 Num1 除以 Num2 以在浮點型變數中獲得結果。

可能會生成兩種型別的異常。

  • 數字轉換錯誤。

  • 除以零異常。處理程式捕獲 CX_SY_CONVERSION_NO_NUMBER 異常以及 CX_SY_ZERODIVIDE 異常。這裡使用異常類的 GET_TEXT( ) 方法來獲取異常的描述。

異常的屬性

以下是異常的五個屬性和方法:

序號 屬性 & 描述
1

Textid

用於為異常定義不同的文字,也影響 get_text 方法的結果。

2

上一頁

此屬性可以儲存原始異常,允許您構建異常鏈。

3

get_text

根據系統的語言返回異常的文字表示形式(字串)。

4

get_longtext

返回異常的文字表示形式的長版本(字串)。

5

get_source_position

給出引發異常時到達的程式名稱和行號。

示例

REPORT ZExceptionsDemo. 
PARAMETERS Num_1 TYPE I. 

DATA res_1 TYPE P DECIMALS 2. 
DATA orf_1 TYPE REF TO CX_ROOT. 
DATA txt_1 TYPE STRING. 

start-of-selection. 
Write: / 'Square Root and Division with:', Num_1. 
write: /. 

TRY. 
IF ABS( Num_1 ) > 150. 
RAISE EXCEPTION TYPE CX_DEMO_ABS_TOO_LARGE. 
ENDIF.
  
TRY. 
res_1 = SQRT( Num_1 ). 
Write: / 'Result of square root:', res_1. 
res_1 = 1 / Num_1. 

Write: / 'Result of division:', res_1. 
CATCH CX_SY_ZERODIVIDE INTO orf_1. 
txt_1 = orf_1→GET_TEXT( ). 
CLEANUP. 
CLEAR res_1. 
ENDTRY. 

CATCH CX_SY_ARITHMETIC_ERROR INTO orf_1. 
txt_1 = orf_1→GET_TEXT( ).

CATCH CX_ROOT INTO orf_1. 
txt_1 = orf_1→GET_TEXT( ). 
ENDTRY. 
IF NOT txt_1 IS INITIAL. 
Write / txt_1. 
ENDIF. 
Write: / 'Final Result is:', res_1.

在此示例中,如果數字大於 150,則會引發異常 CX_DEMO_ABS_TOO_LARGE。對於數字 160,上述程式碼會產生以下輸出。

Square Root and Division with: 160 
The absolute value of number is too high 
Final Result is:  0.00
廣告