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块中恢复一致状态
- 释放外部资源(文件句柄、数据库连接等)
- 记录错误日志供后续分析