ABAP 异常处理

ABAP 异常处理

🚨 异常概述

异常是在程序执行期间出现的问题。当异常发生时:

  • 程序的正常流程中断
  • 程序应用程序异常终止(不推荐)
  • 需要处理这些异常以维持程序稳定性

异常的作用

异常提供了一种将控制从程序的一个部分转移到另一个部分的方法,确保程序在出现错误时能够优雅地处理问题。

🔧 ABAP异常处理关键字

ABAP异常处理建立在四个关键字基础上:

关键字 作用 说明
RAISE 提出异常 表示发生了一些异常情况
TRY 定义尝试块 包含要处理其异常的应用程序编码
CATCH 捕获异常 处理程序捕获异常的位置
CLEANUP 清理操作 恢复一致状态或释放外部资源

TRY-CATCH语法结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.

🎯 引发异常

可以在方法中的任何点、函数模块、子例程等提出异常。有两种方式可以引发异常:

1. ABAP运行时系统引发的异常

由系统自动检测错误情况:

1
2
3
4
5
DATA: y TYPE i VALUE 1.
DATA: z TYPE i VALUE 0.
DATA: result TYPE p LENGTH 8 DECIMALS 2.

result = y / z. " 将导致类型CX_SY_ZERODIVIDE的运行时错误

2. 程序员提出的异常

程序员主动创建并引发异常:

1
2
3
DATA: exep TYPE REF TO CX_DEMO_ERROR.

RAISE EXCEPTION exep. " 使用已存在的异常对象引发异常

🕸️ 捕捉异常

处理程序示例

1
2
3
4
5
6
7
8
9
10
11
12
13
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( ).
ENDTRY.

异常类型说明

异常类 描述 处理场景
CX_SY_ZERODIVIDE 除零异常 数学运算中除数为零
CX_SY_CONVERSION_NO_NUMBER 数字转换错误 无法将字符串转换为数字

🔍 异常的属性和方法

五个重要属性和方法

编号 属性/方法 说明
1 Textid 用于定义异常的不同文本,影响get_text的结果
2 Previous 存储原始异常,允许构建异常链
3 get_text 根据系统语言将异常文本作为字符串返回
4 get_longtext 返回异常文本的长变体
5 get_source_position 给出引发异常的程序名和行号

💡 完整示例

综合异常处理示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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.

输出示例(输入160)

1
2
3
Square Root and Division with: 160
The absolute value of number is too high
Final Result is: 0.00

📝 异常处理最佳实践

1. 异常分类

  • 系统异常:由ABAP运行时系统自动触发
  • 自定义异常:程序员根据业务逻辑主动抛出

2. 异常处理层次



graph TD
    A[TRY块] --> B[具体异常处理]
    A --> C[通用异常处理]
    A --> D[CLEANUP块]

3. 错误恢复策略

  • 在CLEANUP块中恢复一致状态
  • 释放外部资源(文件句柄、数据库连接等)
  • 记录错误日志供后续分析