Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Using exceptions in SE24 global class Builder

Former Member
0 Kudos

Hello all

I'm trying to learn how to use SE24 and I'm a bit stumped on handling exception.

Here's a trivial example showing what I'd like to do.

Can anyone tell me what's wrong. Or point me to a reference.


*& N1	TYPE INT1	Byte Value
*& N2	TYPE INT1	Byte Value
*& OUT	TYPE INT1	Byte Value
*& CX_SY_ARITHMETIC_ERROR		System Exception for Arithmetic Errors

METHOD mult2.
  data: exc type REF TO cx_sy_arithmetic_error .
  out = n1 * n2 .
  IF out > 9.
    RAISE EXCEPTION type exc
  ENDIF.
ENDMETHOD.

1 ACCEPTED SOLUTION

uwe_schieferstein
Active Contributor
0 Kudos

Hello Ed

Using exception classes the rule is the same as in Java:

Either THROW or CATCH the exception.

To catch means to surround the problematic piece of coding using a TRY-CATCH-ENDTRY block.

To throw means to define the exception class as part of the method signature.

The sample report ZUS_SDN_EXCEPTION_IN_LOCCLASS demonstrates how to throw and catch the exception.


*&---------------------------------------------------------------------*
*& Report  ZUS_SDN_EXCEPTION_IN_LOCCLASS
*&
*&---------------------------------------------------------------------*
*& Thread: Using exceptions in SE24 global class Builder
*& <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="817903"></a>
*&---------------------------------------------------------------------*

REPORT  zus_sdn_exception_in_locclass.


*----------------------------------------------------------------------*
*       CLASS lcl_myclass DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass DEFINITION.
  PUBLIC SECTION.

    CLASS-METHODS:
      divide
        IMPORTING
          id_enumerator TYPE i
          id_denominator  TYPE i
        RETURNING
          value(rd_result)  TYPE i
        RAISING
          cx_sy_zerodivide.

ENDCLASS.                    "lcl_myclass DEFINITION



*----------------------------------------------------------------------*
*       CLASS lcl_myclass IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass IMPLEMENTATION.

  METHOD divide.

    " raises division by zero error if id_denominator = 0
        rd_result = id_enumerator / id_denominator.

    " NOTE: since the exception class is defined within the
    "       method signature we do not need to catch it here.

    " BUT: Either catch or throw. Since we throw the exception class
    "      the caller of the method (= main program) must catch it.

  ENDMETHOD.                    "divide

ENDCLASS.                    "lcl_myclass IMPLEMENTATION


DATA: go_error      TYPE REF TO cx_root,
      gd_msg        TYPE bapi_msg.

DATA: go_myclass    TYPE REF TO lcl_myclass,
      gd_result     TYPE i.

PARAMETER:
  p_enum      TYPE i  DEFAULT '10',
  p_denom     TYPE i  DEFAULT '1'.

START-OF-SELECTION.


  TRY.
      CALL METHOD lcl_myclass=>divide
        EXPORTING
          id_enumerator  = p_enum
          id_denominator = p_denom
        RECEIVING
          rd_result      = gd_result.

      WRITE: / p_enum, '/', p_denom, '=', gd_result.

    CATCH cx_sy_zerodivide INTO go_error.
      gd_msg = go_error->get_text( ).
      MESSAGE gd_msg TYPE 'I'.
  ENDTRY.


END-OF-SELECTION.

Regards

Uwe

4 REPLIES 4

uwe_schieferstein
Active Contributor
0 Kudos

Hello Ed

Using exception classes the rule is the same as in Java:

Either THROW or CATCH the exception.

To catch means to surround the problematic piece of coding using a TRY-CATCH-ENDTRY block.

To throw means to define the exception class as part of the method signature.

The sample report ZUS_SDN_EXCEPTION_IN_LOCCLASS demonstrates how to throw and catch the exception.


*&---------------------------------------------------------------------*
*& Report  ZUS_SDN_EXCEPTION_IN_LOCCLASS
*&
*&---------------------------------------------------------------------*
*& Thread: Using exceptions in SE24 global class Builder
*& <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="817903"></a>
*&---------------------------------------------------------------------*

REPORT  zus_sdn_exception_in_locclass.


*----------------------------------------------------------------------*
*       CLASS lcl_myclass DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass DEFINITION.
  PUBLIC SECTION.

    CLASS-METHODS:
      divide
        IMPORTING
          id_enumerator TYPE i
          id_denominator  TYPE i
        RETURNING
          value(rd_result)  TYPE i
        RAISING
          cx_sy_zerodivide.

ENDCLASS.                    "lcl_myclass DEFINITION



*----------------------------------------------------------------------*
*       CLASS lcl_myclass IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass IMPLEMENTATION.

  METHOD divide.

    " raises division by zero error if id_denominator = 0
        rd_result = id_enumerator / id_denominator.

    " NOTE: since the exception class is defined within the
    "       method signature we do not need to catch it here.

    " BUT: Either catch or throw. Since we throw the exception class
    "      the caller of the method (= main program) must catch it.

  ENDMETHOD.                    "divide

ENDCLASS.                    "lcl_myclass IMPLEMENTATION


DATA: go_error      TYPE REF TO cx_root,
      gd_msg        TYPE bapi_msg.

DATA: go_myclass    TYPE REF TO lcl_myclass,
      gd_result     TYPE i.

PARAMETER:
  p_enum      TYPE i  DEFAULT '10',
  p_denom     TYPE i  DEFAULT '1'.

START-OF-SELECTION.


  TRY.
      CALL METHOD lcl_myclass=>divide
        EXPORTING
          id_enumerator  = p_enum
          id_denominator = p_denom
        RECEIVING
          rd_result      = gd_result.

      WRITE: / p_enum, '/', p_denom, '=', gd_result.

    CATCH cx_sy_zerodivide INTO go_error.
      gd_msg = go_error->get_text( ).
      MESSAGE gd_msg TYPE 'I'.
  ENDTRY.


END-OF-SELECTION.

Regards

Uwe

0 Kudos

Thanks for replying Uwe. I'm afraid I'm not asking the question correctly.

What I want to have is an "IF" or "CASE" statement in my method.

When the IF test is false, I want to RAISE an exception similar to what you'd do in a function module.

0 Kudos

Hello Ed

I have modified my sample report to show both ways: classical exceptions and exception classes. However, since exception classes are much more powerful I recommend to use them instead of classical exceptions.

Please note that you cannot mix classical exceptions with exception classes in the same class. Therefore I inactivated method DIVIDE_3.


*&---------------------------------------------------------------------*
*& Report  ZUS_SDN_EXCEPTION_IN_LOCCLASS
*&
*&---------------------------------------------------------------------*
*& Thread: Using exceptions in SE24 global class Builder
*& <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="817903"></a>
*&---------------------------------------------------------------------*

REPORT  zus_sdn_exception_in_locclass.


*----------------------------------------------------------------------*
*       CLASS lcl_myclass DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass DEFINITION.
  PUBLIC SECTION.

    CLASS-METHODS:
      " use exception class
      divide
        IMPORTING
          id_enumerator TYPE i
          id_denominator  TYPE i
        RETURNING
          value(rd_result)  TYPE i
        RAISING
          cx_sy_zerodivide,

      " use exception class
      divide_2
        IMPORTING
          id_enumerator TYPE i
          id_denominator  TYPE i
        RETURNING
          value(rd_result)  TYPE i
        RAISING
          cx_sy_zerodivide.


**      " use classical exception
**      divide_3
**        IMPORTING
**          id_enumerator TYPE i
**          id_denominator  TYPE i
**        RETURNING
**          value(rd_result)  TYPE i
**        EXCEPTIONS
**          arithmetic_error.


ENDCLASS.                    "lcl_myclass DEFINITION



*----------------------------------------------------------------------*
*       CLASS lcl_myclass IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_myclass IMPLEMENTATION.

  METHOD divide.

    " raises division by zero error if id_denominator = 0
    rd_result = id_enumerator / id_denominator.

    " NOTE: since the exception class is defined within the
    "       method signature we do not need to catch it here.

    " BUT: Either catch or throw. Since we throw the exception class
    "      the caller of the method (= main program) must catch it.

  ENDMETHOD.                    "divide


  METHOD divide_2.

    IF ( id_denominator = 0 ).
      RAISE EXCEPTION TYPE cx_sy_zerodivide
        EXPORTING
          textid = cx_sy_zerodivide=>cx_sy_arithmetic_error
          operation = 'DIVIDE'.

    ELSE.
      rd_result = id_enumerator / id_denominator.
    ENDIF.


  ENDMETHOD.                                                "divide_2


**  METHOD divide_3.
**    IF ( id_denominator = 0 ).
**      RAISE EXCEPTION arithmetic_error.
**    ELSE.
**      rd_result = id_enumerator / id_denominator.
**    ENDIF.
**  ENDMETHOD.                                                "divide_3

ENDCLASS.                    "lcl_myclass IMPLEMENTATION


DATA: go_error      TYPE REF TO cx_root,
      gd_msg        TYPE bapi_msg.

DATA: go_myclass    TYPE REF TO lcl_myclass,
      gd_result     TYPE i.

PARAMETER:
  p_enum      TYPE i  DEFAULT '10',
  p_denom     TYPE i  DEFAULT '1'.

START-OF-SELECTION.


**  TRY.
**      CALL METHOD lcl_myclass=>divide
**        EXPORTING
**          id_enumerator  = p_enum
**          id_denominator = p_denom
**        RECEIVING
**          rd_result      = gd_result.
**
**      WRITE: / p_enum, '/', p_denom, '=', gd_result.
**
**    CATCH cx_sy_zerodivide INTO go_error.
**      gd_msg = go_error->get_text( ).
**      MESSAGE gd_msg TYPE 'I'.
**  ENDTRY.


  TRY.
      CALL METHOD lcl_myclass=>divide_2
        EXPORTING
          id_enumerator  = p_enum
          id_denominator = p_denom
        RECEIVING
          rd_result      = gd_result.

      WRITE: / p_enum, '/', p_denom, '=', gd_result.

    CATCH cx_sy_zerodivide INTO go_error.
      gd_msg = go_error->get_text( ).
      MESSAGE gd_msg TYPE 'I'.
  ENDTRY.


**  CALL METHOD lcl_myclass=>divide_3
**    EXPORTING
**      id_enumerator    = p_enum
**      id_denominator   = p_denom
**    RECEIVING
**      rd_result        = gd_result
**    EXCEPTIONS
**      arithmetic_error = 1.
**  IF ( syst-subrc = 0 ).
**    WRITE: / p_enum, '/', p_denom, '=', gd_result.
**  ELSE.
**    MESSAGE 'Arithmetic error'  TYPE 'I'.
**  ENDIF.


END-OF-SELECTION.

Regards

Uwe

0 Kudos

Perfect. That REALLY helped a great deal.

Thanks so much.