部分转自:http://www.cnblogs.com/jiangzhengjun/p/4292428.html
+4.Funcion函数异常处理
说明:
异常处理机制可以有效避免 dump发生,
:异常类是系统预先定义好的全局类或者是由用户自定义的局部或全局的类。 在sap6.10版本里,exception classes已经取代了catchable runtime errors 基于类的异常exception classes 捕获
向上抛出异常
如果Form中出现了运行时错误,但Form签名又没有使用RAISING向上抛,则程序会直接挂掉,所以最好是向上抛
FORM subform RAISING cx_static_check cx_dynamic_check.
...
ENDFORM.
6.1版本以后,TRY…ENDTRY结构:
TRY.
[try_block]
CATCH cx_class1 cx_class2 ... [INTO oref].
[catch_block]
...
[CLEANUP [INTO oref].
[cleanup_block]]
ENDTRY.
CLEARUP是在所在的TRY CATCH发生了异常,但在本TRY CATCH中无法捕获,异常再次向上递交给上层TRY CATCH前被执行的,它不同于Java中的finally
PARAMETERS number TYPE i. DATA result TYPE p DECIMALS 2. DATA oref TYPE REF TO cx_root. DATA text TYPE string. START-OF-SELECTION. TRY. IF ABS( number ) > 100. RAISE EXCEPTION TYPE cx_demo_abs_too_large. ENDIF. TRY. result = 1 / number. WRITE: / 'Result of division:', result. result = SQRT( number ). WRITE: / 'Result of square root:', result. CATCH cx_sy_zerodivide INTO oref."输出0时会在这里捕获 text = oref->get_text( ). CONCATENATE 'CATCH cx_sy_zerodivide : ' text INTO text. CLEANUP."当内层TRY发生了异常,且没有被捕获到,抛到外层TRY前会被执行 CLEAR result. WRITE: / 'cleanup'. ENDTRY. CATCH cx_sy_arithmetic_error INTO oref."输入负数会在这里捕获 text = oref->get_text( ). CONCATENATE 'CATCH cx_sy_arithmetic_error : ' text INTO text. CATCH cx_root INTO oref."输入的数大于100时会在这里捕获 text = oref->get_text( ). CONCATENATE 'CATCH cx_root : ' text INTO text. ENDTRY. IF NOT text IS INITIAL. WRITE / text. ENDIF. WRITE: / 'Final result:', result.
异常的触发:
运行出错时,系统会自动触发预定好的异常类(类似于Java中的运行时异常,6.10前是触发的预定好的错误)
l 可以使用RAISE EXCEPTION手动触发异常(类似Java的throw)
l 对于局部的类的METHODS、过程FORM后加上RAISING 选项来声明要抛出的异常,向上继续抛出(类似Java的throws),全局的函数异常在Exceptions标签里如下设置:
在代码中手动直接抛出异常即可:
IF SY-SUBRC <> 0.
RAISE NO AUTHORITY.
ENDIF.
IF FIELDTYPE NE 'BIN'.
RAISE INVALID_TYPE.
ENDIF.
- 一、CX_ROOT
四个方法:
IF_MESSAGE~GET_TEXT 获取文本
IF_MESSAGE~GET_LONGTEXT 获取长文本
CONSTRUCTOR 构建函数
GET_SOURCE_POSITION 获取源代码位置 -
CX_ROOT Constant Public Type SOTR_CONC
- 二、cx_sy_arithmetic_error
四个方法 《-》 相同
IF_MESSAGE~GET_TEXT
IF_MESSAGE~GET_LONGTEXT
GET_SOURCE_POSITION
CONSTRUCTOR
- 1.抓取数据库操作异常,
*&使用异常类:cx_root
DATA: lo_root1 TYPE REF TO cx_root.
TRY.
INSERT zmdm_matnr FROM ls_zmdm_matnr.
CATCH cx_root INTO lo_root1 .
ENDTRY.
- 2.抓取除法异常,
*&方法一
DATA myref TYPE REF TO cx_sy_arithmetic_error.
DATA err_text TYPE string.
DATA result TYPE i.
TRY.
result = 1 / 0.
CATCH cx_sy_arithmetic_error INTO myref.
err_text = myref->get_text( ).
ENDTRY.
这个写法与java是相似的
*&方法二、(新式的)
DATA result TYPE p DECIMALS 2.
DATA oref TYPE REF TO cx_root.
DATA text TYPE string.
DATA i TYPE i.
TRY .
i = 1 / 0.
CATCH cx_root INTO oref.
text = oref->get_text( ).
WRITE: '---' , text.
RAISE EXCEPTION oref.”注:如果有此句,则不能放在Function中,否则报:Old and class-based exceptions must not be used the same time
ENDTRY.
- 3.抓取上传数值类型字段异常,(防止上传过程系统dump)
DATA: O_CX TYPE REF TO CX_ROOT.
DATA:LS_UPLOAD-MENGE TYPE STRING,
LS_OUTPUT-MENGG TYPE MENGE_D. TRY . MOVE LS_UPLOAD-MENGE TO LS_OUTPUT-MENGE. CATCH CX_ROOT INTO O_CX. LV_MSG = O_CX->IF_MESSAGE~GET_TEXT( ). CONCATENATE LS_OUTPUT-MESG LV_MSG INTO LS_OUTPUT-MESG SEPARATED BY ';'. ENDTRY.
IF LS_UPLOAD-MENGE = 'AAA'.
LV_MSG = 无法将参数 'AAA' 解释为数字
ENDIF.
- 4.+4.Funcion函数异常处理
Funcion函数不会主动向外抛出运行时错误,所以要先在Function手动CATCH,再手动向外抛,如果出现运行时错误不抛出,则Function与会直接宕掉:
转自 江正军
三类异常:
l CX_STATIC_CHECK
l CX_DYNAMIC_CHECK
l CX_NO_CHECK
具体的异常类继承结构请查看SAP帮助,输入“EXCEPTION”
类比:CX_NO_CHECK类似于Java中的Error,CX_DYNAMIC_CHECK类似于Java中的RuntimeException,CX_STATIC_CHECK类似于Java检测性异常
CX_STATIC_CHECK是一个抽象类,一般自己定的异常都要求继承于它。在程序中使用RAISE EXCEPTION 手动抛出这类异常时,方法或过程接口上一定要显示的通过RAISING 来向上层抛出异常(或者直接在方法或过程中进行处理也可以),否则静态编译时就会出现警告。
CX_NO_CHECK类型的异常一般表示系统资源不足引起的,不能在方法或过程接口后面抛出CX_NO_CHECK类型的异常,它会被隐含的抛出与传递。系统中已有预定义这类异常。
如果程序逻辑能够排除可能性的潜在性错,相应的异常就可能不用处理或继续抛出,此类情况下可以使用CX_DYNAMIC_CHECK类型的异常,这与Java中的运行时异常相似,一旦发生也该类异常,表示问题出现在程序的本身设计上,程序设计不严谨(如没有判断空指针问题)。ABAP大多数的系统预定义的异类都是属于该类型异常,这就意味着不需要处理或抛出ABAP语句可能出现的每一种异常,但一旦发生了该类异常,则表示程序的逻辑出现了问题,程序执行的结果将不会在正确。
异常类可以被定义成全局的类或者是局部的异常类,全局异常类名称以CX_, YCX_, ZCX_为前缀。系统里预定义好的全局异常类都是能CX_SY_为前缀来命名的。
如果是通过Class Builder创建的全局异常类时,由于构造器是默认创建好的,不能传递参数,所以异常文本ID只能通过TEXTID传递,但局部异常类没有这个限制。
如果在抛出的异常类在构造的过程中(构造函数中)发生了异常,则会使用CX_SY_NO_HANDLER异常来代替原来的异常实例。
函数异常的定义、抛出、与处理
CALLFUNCTION时一定不能省略Exceptions选项(EXCEPTIONS表示函数接口需要抛出异常,如果函数里抛出了异常,但调用时接口上没有加上该选项,则程序运行时会中断),否则异常不能捕获,运行时会出错。其实Exception先项就相当于TRY ... CATCH...
Exception Handling
关于异常更多详情,请参考SAP 帮助Exception Handling