Программная ошибка abap

Привет, Всем!!!

Помогите разрешить некорректную ситуацию, связанную с программной ошибкой в системе SAP BW(Версия компонентов системы SAP_BASIS и SAP_BW — 702).
Некорректная ситуация заключается в следующем. Мне потребовалось проанализировать содержимое PSA таблицы источника данных «2LIS_02_SCL». В транзакции «RSA1» зашёл в закладку «Источники данных», выделил источник данных «2LIS_02_SCL» и выбрал из контекстного меню «Администрирование». Выбрал требуемый запрос и нажал кнопку «PSA-ведение». В окне «PSA-ведение» выделил требуемый для анализа пакет данных и нажал на кнопку «Дальше». Обычно по нажатию кнопки «Дальше» система предоставляет содержимое выбранного пакета данных в формате ALV. В моём случае я получил дамп со следующим вложением:

Категория Программная ошибка ABAP
ДинамОшибка GETWA_NOT_ASSIGNED
АВАР-прогр. SAPLSLVC
Anwendungskomponente BC-SRV-ALV
Дата и время 30.05.2012 10:32:28

Краткий текст Field symbol has not yet been assigned.

Что произошло? Error in the ABAP Application Program

The current ABAP program «SAPLSLVC» had to be terminated because it has
come across a statement that unfortunately cannot be executed.

Место инициации динамической ошибки: Программа SAPLSLVC
Include LSLVCF36
Строка 3.273
Тип модуля (FORM)
Имя модуля FILL_DATA_TABLE

Попытался поискать ноты по устранению выше указанной программной ошибки ABAP. Нашёл ряд нот, но все они ссылаются на пакеты поддержки, которые у нас уже установлены в системе BW.

У нас сейчас в системе BW стоят следующие последние пакеты поддержки:
SAP_BASIS: SAPKB70211;
SAP_BW: SAPKW70211.

Выскажите ваши идеи по выше описанной ситуации для нахождения решения или может быть кто то уже сталкивался с подобной ситуацией и нашёл уже решение, нашёл ноту.
В случае если кто то уже нашёл ноту вышлите мне пожалуйста номер ноты. Я мог просто не найти её.

Заранее спасибо,
Сергей.

Preface – This post is part of the ABAP Beginner series.

Introduction

A programmer always tries to code in such a way that his code is bug free and full proof. But there are certain scenarios, where his codes can fail. In such case, if the coder already knows the scenarios, then he handle them in form of Error handling. But, in case of situations, where an error can be generated due to unknown situations and left un-handled can cause serious dumps. For these scenarios, we have exception handling in SAP. In this article we will explore all scenarios of Exception and Error Handling in ABAP Reports

Exception and Error Handling in SAP ABAP Reports

As discussed above, a coder is required to handle known issues as well as intended error messages. These messages are shown to user in the output via MESSAGE statement.

Different ways to catch Errors/Exception

ABAP provides various ways to catch errors in an ABAP program.

  1. Using System Variable

The simplest way is to use their system variables.

 SY-SUBRC EQ  0. "This statement indicates that an operation completed successfully.
 SY-SUBRC NE  0. "This statement indicates that an operation has failed.

This way works directly if the entire code of report was process within the same program. It means, it cannot catch an error directly in case you have processed a Function Module or ABAP Class statements. For those entity, we need to raise exception from their end, and then exception can be handled in the report and processed accordingly.

  1. Catching Errors based on Exception

In case, we implement a function module or method of a class, then it is important to raise exception from these classes and then we can catch these exceptions in report and show respective error.

For Example:

CALL FUNCTION 'Test_Function'

     EXPORTING

          DELIMITER =   ':'

          STRING        =   lv_string

     IMPORTING

          HEAD           =   lv_head

          TAIL             =   lv_tail

     EXCEPTIONS

          NOT_FOUND   =  1

          OTHERS       =   2.




CASE SY-SUBRC.

     WHEN 1. ...

// Show Error Message

     WHEN 2. ...

// Show Error Message

     WHEN OTHER.

// Show Error Message

ENDCASE.
  1. Using TRY CATCH ENDTRY

In case an exception is raised via a method of class, or an unexpected exception is raised, in these cases, we use TRY CATCH functionality of SAP ABAP. This is one of the best full proof way to handle all types of exceptions.

Example:

TRY.

     //Call your class or function module here

CATCH CX_SY_ZERODIVIDE INTO O_REF. // The exception you have raised there

     MESSAGE “Your Error Message”.
ENDTRY.

Different ways to show Messages

  1. Using ABAP Statement

Syntax:

MESSAGE ‘<Enter Your Text here>’ TYPE ‘Enter the type of Message here’.

Types of Message

ABAP provides the following 6 types of messages:

Message Type Meaning Explanation
A Termination This message is shown during program termination.
E Error This message is shown during Error.
I Information This message is used to show any information.
S Success This shown in the status of the Output screen.
W Warning It behaves like an error message.
X Exit It causes a short dump with error message.
  1. Using Predefined Function Modules

ABAP provides following function modules that can be used to store, format and show messages altogether:

Function Module Usage
MESSAGES_INITIALIZE To Initialize the messages.
MESSAGE_STORE To Store the messages to be displayed.
MESSAGES_SHOW To Display all the messages together on a pop up
FORMAT_MESSAGE To Format the messages
HR_DISPLAY_ERROR_LIST To display all the error messages

Example:

  1. Using Message Statement
MESSAGE 'This is an error message' TYPE 'E'.
  1. Using Multiple functions to store and show messages:
" It is Initialized only initially...
* Initialize your messages
  CALL FUNCTION 'MESSAGES_INITIALIZE'
    EXCEPTIONS
      log_not_active       = 1
      wrong_identification = 2
      OTHERS               = 3.

"One by one append all your messages here
      PERFORM store_messages USING 'E'
                                   w_pn
                                   w_batch2
                                   w_werks
                                   ' '
                                   w_msgno.

FORM store_messages USING p_msgty
                          p_msgv1
                          p_msgv2
                          p_msgv3
                          p_msgv4
                          p_txtnr.
  IF p_msgty EQ 'E'.
    w_err_fg = 'X'.
  ENDIF.
* Store all your messages meant to be displayed
  CALL FUNCTION 'MESSAGE_STORE'
    EXPORTING
      arbgb                  = 'ZCCH001'
      msgty                  = p_msgty
      msgv1                  = p_msgv1
      msgv2                  = p_msgv2
      msgv3                  = p_msgv3
      msgv4                  = p_msgv4
      txtnr                  = p_txtnr
    EXCEPTIONS
      message_type_not_valid = 1
      not_active             = 2
      OTHERS                 = 3.

ENDFORM.                    " STORE_MESSAGES

"In the end fetch all your message and show them altogether
* This displays all the messages in a popup
  CALL FUNCTION 'MESSAGES_SHOW'
    EXPORTING
      show_linno         = ' '
    IMPORTING
      e_exit_command     = wa_exit_command
    EXCEPTIONS
      inconsistent_range = 1
      no_messages        = 2
      OTHERS             = 3.
  1. Using HR_DISPLAY_ERROR_LIST
DATA:

it_error        TYPE STANDARD TABLE OF HRERROR,"TABLES PARAM

wa_error     LIKE LINE OF it_error .

DATA(ld_no_popup) = 'some text here'.

DATA(ld_no_print) = 'some text here'.

DATA(ld_no_img) = 'some text here'.

DATA(ld_no_msgno) = 'some text here'.

DATA(ld_linesize) = '123 '.

DATA(ld_listheader) = 'Check type of data required'.

DATA(ld_colheader) = 'Check type of data required'.

DATA(ld_hidemsg) = 'some text here'.

 

 

"populate fields of struture and append to itab

append wa_error to it_error.

.

CALL FUNCTION 'HR_DISPLAY_ERROR_LIST'

* EXPORTING

*   no_popup =                   ld_no_popup

*   no_print =                   ld_no_print

*   no_img =                     ld_no_img

*   no_msgno =                   ld_no_msgno

*   linesize =                   ld_linesize

*   listheader =                 ld_listheader

*   colheader =                  ld_colheader

*   hidemsg =                    ld_hidemsg

* TABLES

*   error =                      it_error

  EXCEPTIONS

    INVALID_LINESIZE =           1

    .  "  HR_DISPLAY_ERROR_LIST

IF SY-SUBRC EQ 0.

  "All OK

ELSEIF SY-SUBRC EQ 1. "Exception

  "Add code for exception here

ENDIF.
  • Barry Allen

    A Full Stack Developer with 10+ years of experience in technical content creation.

    View all posts

Обработка исключений

Обработка исключений — это то, что происходит, когда система выдает ошибку.

Во время выполнения программы программа может столкнуться с ошибками. Иногда ошибки вносятся программистами случайно, но большинство ошибок связано с неправильным обращением с приложением. Ошибочные ситуации можно предвидеть во время разработки приложения, но просто невозможно избежать всех типов ошибок.

Обзор исключений

Отображение сообщения в процедуре на самом деле не имеет смысла, поскольку сообщения предназначены для отображения пользователю. В случае с процедурами рекомендуемым способом обработки ситуации с ошибкой является возбуждение исключения и предоставление вызывающей программе возможности решить, что делать с исключением.

Например, предположим, что мы разработали функциональный модуль, который принимает номер материала в качестве параметра импорта и экспортирует различные сведения о материале. Если номер материала, импортированный в функциональный модуль, недействителен, то вместо отображения сообщения о том, что номер материала недействителен, мы можем вызвать исключение в функциональном модуле, которое вызывающая программа может обработать в соответствии со своими функциональными требованиями. То есть вызывающая программа может либо показать сообщение об ошибке, либо выполнить другие действия. Кроме того, поскольку процедуры предназначены для повторного использования, вызывая исключения в процедуре, разные программы могут обрабатывать их по-разному в соответствии со своими конкретными требованиями.

Процедурная обработка исключений

До появления исключений на основе классов только функциональные модули и методы могли вызывать самоопределяемые обрабатываемые исключения, а логика обработки исключений смешивалась с реальной логикой программы.

Поддержка исключений с помощью функциональных модулей

Исключения статически поддерживаются в функциональном модуле с пояснительным текстом, объясняющим ситуацию исключения. Когда возникает это исключение, системное поле SY-SUBRC устанавливается с номером исключения, который вызывающая программа может проверить, чтобы реализовать пользовательскую логику обработки ошибок.

Функциональный модуль Z_TEST_EXCEPTION_EXAMPLE поддерживает два исключения: NOT_FOUND и NO_AIRLINE_DATA. При вызове этого функционального модуля в функциональном модуле возникает соответствующее исключение, если возникает ситуация ошибки. Вызывающая программа проверяет значение SY-SUBRC, чтобы идентифицировать исключение и поддерживать соответствующую логику обработки ошибок в программе.

DATA lt_spfli TYPE spfli_tab.
CALL FUNCTION 'Z_TEST_EXCEPTION_EXAMPLE'
  EXPORTING
    iv_id        = 'LH'
  IMPORTING
    et_itab      = lt_spfli
  EXCEPTIONS
    NOT_FOUND       = 1
    NO_AIRLINE_DATA = 2
    OTHERS          = 3.
CASE sy-subrc.
  WHEN 1.
* Обработка исключения
* NOT_FOUND
  WHEN 2.
* Обработка исключения
* NO_AIRLINE_DATA  
  WHEN OTHERS.
* Обработка других исключений
ENDCASE.

Эти самоопределяемые исключения поддерживаются вручную в функциональных модулях и методах и вызываются с помощью оператора RAISE внутри функционального модуля или метода.

Когда возникает первое исключение, функциональный модуль закрывается, и управление передается обратно вызывающей программе без выполнения дополнительного кода в функциональном модуле. Если вызывающая программа не перехватывает исключение, генерируется ошибка времени выполнения (короткий дамп). По этой причине всегда рекомендуется использовать ключевое слово EXCEPTIONS в вызове функционального модуля (CALL FUNCTION) для перехвата исключений, даже если вы не планируете реализовывать какую-либо пользовательскую логику для исключения.

Поддержка исключений с помощью методов

Подобно функциональным модулям, исключения можно поддерживать в методах с помощью Class Builder, удерживая курсор на методе и выбирая кнопку «Исключение», как показано ниже.

В столбце «Исключение» на вкладке «Метод» дайте имя исключению и сохраните описание, объясняющее исключение, чтобы разработчики, вызывающие метод, могли понять, почему возникает это исключение.

Как показано, в методе можно вызвать исключение с помощью оператора RAISE

.

Обратите внимание, что исключения специфичны для процедуры в том смысле, что если исключение поддерживается для функционального модуля, оно может быть вызвано только внутри этого функционального модуля и не может быть вызвано другими функциональными модулями функциональной группы. Точно так же исключение, поддерживаемое для метода, может быть вызвано только внутри этого метода и не может быть вызвано другими методами класса.

Исключений для локальных классов

Для локальных классов исключения можно определить с помощью оператора EXCEPTIONS в части определения класса, как показано ниже. Исключения, определенные в части определения класса, могут быть вызваны методами, реализованными в части реализации того же класса.

CLASS lcl_test_class DEFINITION
  PUBLIC.

  PUBLIC SECTION.
    CLASS-METHODS read_spfli_into_table
      IMPORTING
        VALUE(iv_id)   TYPE spfli-carrid DEFAULT 'LH '
      EXPORTING
        VALUE(et_itab) TYPE spfli_tab
      EXCEPTIONS
        not_found         "Запись не найдена
        no_airline_data . "Нет данных авиакомпании

ENDCLASS.

Мы определили исключение NOT_FOUND в части определения класса LCL_TEST_CLASS. Исключения определяются с помощью ключевого слова EXCEPTIONS. Рекомендуется поддерживать комментарий с кратким описанием исключения.

Обработка исключений на основе классов

Исключения на основе классов (объектно-ориентированные) помогают отделить логику обработки исключений от основной логики программирования, обрабатывая исключения в отдельном блоке. В предыдущем разделе, посвященном процедурным методам обработки исключений, вы видели, что помимо проверки системного поля SY-SUBRC для идентификации исключения, информации об исключении не так много.

Кроме того, поскольку самоопределяемые исключения поддерживаются только в функциональных модулях и методах, в обычных программах нет правильного способа обработки ошибок. Например, если в подпрограмме возникает ситуация ошибки, в которой самоопределяемые исключения не поддерживаются, как мы можем с этим справиться?

Один из способов — передать структуру ошибки или какую-либо переменную в интерфейс параметров и проверить ее после выполнения подпрограммы, как показано ниже.

DATA: lv_carrid  TYPE scarr-carrid,
      lt_spfli   TYPE spfli_tab,
      lv_retcode.

PERFORM read_spfli_into_table USING    lv_carrid
                              CHANGING lt_spfli
                                       lv_retcode.
IF lv_retcode IS INITIAL.
*Логика программы
ELSE.
*Логика обработки ошибок
ENDIF.

FORM read_spfli_into_table USING    iv_id
                           CHANGING ct_itab TYPE spfli_tab
                                    cv_retcode.

    SELECT SINGLE carrid INTO @DATA(lv_carrid) FROM scarr  WHERE carrid = @iv_id.
    IF sy-subrc NE 0.
      cv_retcode = 1.
    ENDIF.
    SELECT * FROM spfli WHERE carrid = @iv_id INTO TABLE @ct_itab.
    IF sy-subrc NE 0.
      cv_retcode = 2.
    ENDIF.
ENDFORM.

Как вы можете видеть, код использует параметр LV_RETCODE, чтобы зафиксировать ситуацию с ошибкой и соответствующим образом построить логику программы для обработки исключения. Однако это не самый элегантный способ обработки исключений, и интерфейс может вскоре стать загроможденным, если необходимо обработать множество исключительных ситуаций. Это также создает проблемы при пересылке исключения, если исключение необходимо обработать в другом блоке обработки. Например, большинство BAPI реализуют структуру ошибок в интерфейсе для захвата ошибки. В этой структуре ошибки фиксируется большая часть информации об ошибке, например тип ошибки, идентификатор ошибки, сообщение и т. д.

Теперь мы хотим передать эти сведения об ошибке другому функциональному модулю, вызываемому в BAPI, в котором может быть обработано исключение. Для этого нам нужно убедиться, что BAPI и функциональный модуль, вызываемый в BAPI, имеют схожие структуры ошибок; в противном случае нам нужно вручную преобразовать данные и присвоить их новой структуре ошибок функционального модуля.

Вопреки тому, что предполагают многие разработчики, исключения на основе классов не ограничиваются объектами ABAP. Их можно использовать в любом блоке обработки. Исключения на основе классов обрабатываются с помощью специального блока, называемого блоком TRY. Используя операторы CATCH и CLEANUP, мы можем обрабатывать исключения в блоке TRY. Оператор CATCH может перехватывать несколько исключений внутри блока, а оператор CLEANUP позволяет выполнять задачи очистки при выходе из исключения. Например, если вы открываете файл для вывода и сталкиваетесь с исключением при передаче одной из записей, то блок очистки позволяет закрыть файл.

Raising Exceptions

Исключения возникают в нескольких ситуациях — либо программно с помощью оператора RAISE EXCEPTION, либо автоматически средой выполнения ABAP. Например, если мы выполним код ниже, это приведет к ошибке времени выполнения.

DATA : lv_unit_value  TYPE i,
       lv_total_value TYPE i VALUE 20,
       lv_quantity    TYPE i.
lv_unit_value = lv_total_value / lv_quantity.

Показан класс исключений, который выдается системой при делении операнда на ноль. Мы можем избежать короткого дампа, перехватив исключение в нашей программе и выйдя из ситуации исключения.

Ниже показан синтаксис реализации блока TRY для обработки исключений.

DATA lx_ex TYPE REF TO cx_sy_zerodivide.
DATA : lv_unit_value  TYPE i,
       lv_total_value TYPE i VALUE 20,
       lv_quantity    TYPE i.
TRY. "Начало блока TRY
    lv_unit_value = lv_total_value / lv_quantity.
*Другая логика программирования
  CATCH cx_sy_zerodivide INTO lx_ex.
    WRITE :/'Короткий текст ошибки:' , lx_ex->get_text( ).
    WRITE :/'Длинный текст ошибки:' , lx_ex->get_longtext( ).
  CLEANUP.
* Любая логика очистки
ENDTRY. "Конец TRY блока

Код приводит к выводу, показанному ниже. Здесь система не генерировала короткий дамп, потому что мы поймали исключение в программе и обработали исключительную ситуацию программно. Хорошая практика программирования состоит в том, чтобы избегать таких исключительных ситуаций, проверяя знаменатель перед его использованием при делении (например, IF lv_quantity IS NOT INITIAL ).

Перехватываемые и неперехватываемые исключения

Существует два типа исключений, генерируемых системой: перехватываемые и неперехватываемые. Для перехватываемых исключений мы можем использовать структуру управления TRY для перехвата исключения в программе, неперехватываемые исключения приводят к ошибке времени выполнения.

Мы можем найти информацию о различных возможных исключениях, вызванных системой, проверив документацию по любому конкретному ключевому слову, и реализовать подходящую обработку исключений в нашей программе. Все классы системных исключений начинаются с CX_SY_.

Возвращаясь к коду, мы определили перехватываемое исключение CX_SY_ZERODIVIDE, которое вызывается системой, когда она сталкивается со значением, делящимся на ноль. Единственная ситуация, в которой системное исключение не возникает при таких обстоятельствах, — это когда числитель также равен нулю. Здесь CX_SY_ZERODIVIDE — это глобальный класс с определенными компонентами.

Как видно, класс CX_SY_ZERODIVIDE реализует интерфейс IF_MESSAGE с двумя методами: GET_TEXT и GET_LONGTEXT. Псевдонимы для этих методов сохраняются на вкладке Псевдонимы.

Мы определили ссылочный объект LX_ER, ссылающийся на статический тип CX_SY_ZERODIVIDE. В управляющей структуре TRY оператор CATCH cx_sy_zerodivide INTO lx_ex создает экземпляр объекта LX_EX. Мы получили доступ к короткому и полному тексту ошибки, вызвав методы GET_TEXT и GET_LONGTEXT соответственно.

При желании мы также сохранили блок CLEANUP, в котором может храниться подходящий код выхода для корректного выхода из процедуры. Например, блок CLEANUP можно использовать для закрытия любых открытых файлов или отката любых обновлений базы данных.

Если вы внимательно посмотрите на класс CX_SY_ZERODIVIDE, то увидите, что он наследуется от суперкласса CX_SY_ARITHMETIC_ERROR. Класс CX_SY_ARITHMETIC_ERROR, в свою очередь, наследуется от суперкласса CX_DYNAMIC_CHECK, который наследуется от CX_ROOT

Базовым классом для всех классов исключений является CX_ROOT, который реализует интерфейсы IF_MESSAGE и IF_SERIALIZABLE_OBJECT. Интерфейс IF_MESSAGE содержит методы GET_TEXT и GET_LONGTEXT, позволяющие извлечь сообщение об ошибке. Интерфейс IF_SERIALIZABLE_OBJECT используется для сериализации объектов — процесса, в котором объект преобразуется в формат сериализации (например, XML, CSV), который может быть передан для создания клона объекта в той же или другой системе. Интерфейс IF_SERIALIZABLE_OBJECT должен быть реализован, если объект исключения необходимо сериализовать. Класс CX_ROOT также реализует другой метод, GET_SOURCE_position, который возвращает позицию в исходном коде, вызвавшую ошибку.

При перехвате исключений на основе классов информация об исключении захватывается объектом, который является экземпляром класса, наследуемого от одного из трех глобальных абстрактных классов: CX_STATIC_CHECK, CX_DYNAMIC_CHECK или CX_NO_CHECK. Эти три глобальных абстрактных класса, в свою очередь, являются подклассами CX_ROOT. Например, мы можем определить ссылочный объект LX_ER как экземпляр класса CX_ROOT вместо класса CX_SY_ZERODIVIDE и по-прежнему иметь возможность перехватывать исключение, как показано в листинге 9.6. Однако это сделает логику ошибки общей и упустит какие-либо конкретные детали обработки исключений, поддерживаемые в конкретном классе исключений.

Как уже отмечалось, при определении пользовательского класса исключений он должен наследоваться от одного из трех классов:

CX_STATIC_CHECK 

Если класс исключения, являющийся подклассом CX_STATIC_CHECK, вызывается в функциональном модуле или методе, он должен быть либо определен в сигнатуре (интерфейс параметра), либо перехвачен в процедуре внутри блока TRY. В противном случае средство проверки синтаксиса выводит предупреждающее сообщение.

CX_DYNAMIC_CHECK

Подобно CX_STATIC_CHECK, если класс исключения, который является подклассом CX_DYNAMIC_CHECK, возникает в функциональном модуле или методе, он должен быть либо определен в сигнатуре (интерфейс параметра), либо перехвачен в процедуре внутри блока TRY. В противном случае компилятор не выдаст статическое предупреждающее сообщение, а выдаст ошибку времени выполнения.

CX_NO_CHECK

Класс исключения, который является подклассом CX_NO_CHECK, не может быть определен в сигнатуре функционального модуля или метода. Он неявно объявлен по умолчанию и всегда передается вызывающей стороне.

Поскольку CX_STATIC_CHECK проверяется компилятором во время разработки, рекомендуется использовать этот класс для определения классов исключений. Большинство системных исключений являются производными от CX_DYNAMIC_CHECK.

Глобальное определение классов исключений

Чаще всего мы определяем классы исключений глобально, чтобы их можно было использовать в нескольких программах. Действия по созданию класса исключения в Class Builder аналогичны действиям по созданию любого обычного класса, за исключением того, что класс исключения должен наследовать CX_STATIC_CHECK, CX_DYNAMIC_CHECK или CX_NO_CHECK или любой класс, наследующий эти классы.

Кроме того, классы исключений должны следовать соглашению об именах CX_ для пространства имен SAP и ZCX_ для пространства имен клиента. Флажок «Класс исключения» также установлен для класса исключения.

Флажок «С классом сообщений» позволит вам использовать класс сообщений для хранения сообщений.

Вы заметите, что Class Builder создаст класс исключений, которая похожа на обычный класса, за исключением незначительных дополнительных опций. Например, вы увидите вкладку «Тексты», которая недоступна при создании обычных классов.

SAP рекомендует не определять новые методы и не переопределять унаследованные методы.

Исключение можно вызвать внутри функционального модуля, используя синтаксис RAISE EXCEPTION TYPE класс_исключений.

Локальное определение классов исключений

Локальные классы исключений могут быть определены для локальной работы с исключениями внутри программы. Синтаксис определения локального класса исключений подобен обычному классу, за исключением того, что он должен наследовать CX_STATIC_CHECK, CX_DYNAMIC_CHECK или CX_NO_CHECK. Соглашение об именах LCX_ используется для локальных классов исключений.

Помимо их видимости, работа с локальными классами исключений аналогична работе с глобальными классами исключений.

Сообщения в классах исключений

Классы исключений позволяют нам изящно выйти из ситуации исключения. Однако иногда исключение вызвано ошибкой, для исправления которой может потребоваться вмешательство человека. В таких ситуациях мы можем перехватить сообщение, когда возникнет исключение, чтобы можно было идентифицировать ошибку. Для этого мы можем передать текстовое сообщение с исключением. Тексты также могут иметь значения динамических полей для дополнения сообщения.

Тексты могут храниться непосредственно в классе исключений, который использует онлайн-репозиторий текстов (OTR), или мы также можем использовать сообщения из класса сообщений (транзакция SE91).

Использование онлайн-репозитория текстов

Следующие шаги помогут вам поддерживать сообщения в классах исключений:

1. На вкладке Атрибуты класса исключений определите атрибут со значением, которое вы хотите передать в сообщении. В этом примере мы поддерживаем MV_CARRID в качестве имени атрибута типа S_CARR_ID, поскольку мы планируем передать краткое название авиакомпании в сообщении об исключении. После определения атрибута нажмите «Активировать».

2. На вкладке «Тексты» сохраните идентификатор исключения и текст. Вы можете передать значение атрибута в сообщении, сохранив имя атрибута между амперсандами (&). Здесь мы сохранили идентификатор исключения как INVALID_CARRID, а текст как Нет данных авиакомпании &MV_CARRID&, заключив атрибут в амперсанды. Вы также можете сохранить длинный текст сообщения, нажав кнопку «Длинный текст». Когда закончите, нажмите Активировать.

3. В этот момент на вкладке «Атрибуты» вы увидите, что определенный идентификатор исключения добавляется как константа типа SOTR_CONC. Поддерживаемый текст сохраняется в OTR и поддерживает интернационализацию (переводы).

4. Конструктор класса автоматически добавляет атрибуты, которые вы добавили в качестве параметров импорта, в свою сигнатуру, которую можно передать при возникновении исключения с помощью ключевого слова EXPORTING. Конструктор гарантирует, что все атрибуты инициализированы правильно. Атрибут textid хранит идентификатор исключения для доступа к соответствующему тексту. Предыдущий атрибут хранит предыдущие исключения в контексте. Ниже показаны сигнатура и код инициализации метода конструктора после добавления атрибута MV_CARRID.

5. Чтобы сгенерировать исключение и передать сообщение с названием авиакомпании, вы можете написать оператор RAISE EXCEPTION, как показано на ниже. Здесь вы вызываете конструктор и передаете TEXTID, обращаясь к константе INVALID_CARRID, определенной в атрибутах класса. Эта константа относится к соответствующему идентификатору исключения. Вы также передаете номер материала атрибуту MV_CARRID, чтобы поле &MV_CARRID& в тексте было заменено значением.

Перехват исключения в программе.

DATA lt_spfli TYPE spfli_tab.
TRY.
    CALL FUNCTION 'Z_TEST_EXCEPTION_EXAMPLE'
      EXPORTING
        iv_id   = 'LR'
      IMPORTING
        et_itab = lt_spfli.
  CATCH zcx_test_exception INTO DATA(lx_msg).
    WRITE / lx_msg->get_text( ).
ENDTRY.

Использование сообщений из класса сообщений

Чтобы использовать сообщения из класса сообщений, выполните следующие действия:

1. Установите флажок «С классом сообщения». Как только этот флажок установлен, система автоматически добавляет к классу сообщений интерфейсы IF_T100_MESSAGE, IF_T100_DYN_MSG, который используется для доступа к сообщениям, хранящимся в классе сообщений.

2.Чтобы использовать сообщение из класса сообщений, перейдите на вкладку «Тексты», сохраните идентификатор исключения и нажмите кнопку «Текст сообщения».

3. В окне «Назначить атрибуты класса исключений сообщению» укажите имя класса сообщений и идентификатор сообщения (номер сообщения). Если вы хотите передать значение атрибута в сообщение, вы можете выбрать атрибут из раскрывающегося списка рядом с каждым полем атрибута. Вы можете передать до четырех атрибутов.

4. Чтобы сгенерировать исключение и передать сообщение с названием авиакомпании, вы можете написать оператор RAISE EXCEPTION.

Перехват исключения в программе.

DATA: lt_spfli TYPE spfli_tab,
      lv_id    TYPE s_carr_id VALUE 'LR'.

DO 2 TIMES.
  TRY.
      CALL FUNCTION 'Z_TEST_EXCEPTION_EXAMPLE'
        EXPORTING
          iv_id   = lv_id
        IMPORTING
          et_itab = lt_spfli.
    CATCH cx_static_check INTO DATA(lx_msg).
      WRITE / lx_msg->get_text( ).
  ENDTRY.
  lv_id = 'AB'.
ENDDO.

Использовали вышестоящий класс исключений cx_static_check, для обоих классов исключений.

Результат:

Использование дополнения MESSAGE для создания исключения

В SAP NetWeaver 7.5 появилось новое дополнение MESSAGE, которое можно использовать при возникновении исключений. Используя дополнение MESSAGE, вы можете передать спецификации сообщения, такие как тип сообщения, идентификатор сообщения и номер сообщения, а также заполнители для сообщения.

Если класс сообщения реализует интерфейс IF_T100_DYN_MSG, вы можете передать тип сообщения, используя дополнение TYPE, а заполнители для сообщения можно передать, используя дополнение WITH. Однако, если класс сообщения реализует интерфейс IF_T100_MESSAGE, то вы не можете передать тип сообщения

и заполнители сообщений, использующие дополнение WITH.

  RAISE EXCEPTION TYPE zcx_test_exception_message
      MESSAGE ID sy-msgid
      TYPE sy-msgty
      NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

В пример показан кода для создания исключения, когда интерфейс IF_T100_DYN_MSG реализован в классе сообщения. В этом примере мы используем дополнение MESSAGE для передачи спецификаций сообщения. Атрибуты и тип сообщения можно передавать напрямую, не определяя их отдельно в классе исключений, поскольку интерфейс IF_T100_DYN_MSG обеспечивает встроенную поддержку.

What is Exception?

Exception is an runtime errors that occurs during the program execution. The runtime errors can be of two types —

  • Catchable Runtime Errors which can be caught using the exception handling.
  • Non-Catchable Runtime Errors which always results the termination of program.

Normally exceptions might occur due to performing an invalid operation or invalid movements. Exception disturbs the normal flow of the program execution.

Due to the exception, the program execution terminates abnormally which is not expected.
The exceptions need to be handled to skip the termination of the program and get the expected result.

Exception Categories —

Exceptions are represented by objects that are instances of classes. All those type of classes are called as exception classes.
cx_root is the root class of all the exception classes and the major classes inherited from this class.

The root class is used to define handlers for all types of exceptions. The super class cx_root derives three major classes and those are —

  • CX_STATIC_CHECK – Used for the exception handler static protection.
    Exceptions of this category must be declared explicitly in the procedure interface.
    It is verified by both the compiler and runtime system.
  • CX_DYNAMIC_CHECK – Used for error situations that can be prevented by preconditions.
    Exceptions of this category should also declare explicitly in the procedure interface.
    It is verified by runtime system only.
  • CX_NO_CHECK – Used for situations that cannot handled immediately.
    Exceptions of this category cannot be declared explicitly in the procedure interface.

Exception Attributes & Methods —

Exception clauses inherit the below attributes and methods from cx_root —

Attributes & Methods Description
Textid This attribute used to define different texts for exceptions.
Effects the result of the method get_text.
Previous This attribute can store the original exception which allows us to build a chain of exceptions.
get_text This method returns the textual representation as a string according to the exception system language.
get_longtext This method returns the long variant of the exception textual representation as a string.
get_source_position This method returns the program name, include name and line number where the exception was raised.

What is Exception Handling?

ABAP supports exception handling for handling the exceptions to get the expected results.
Exception handling provides a way to transfer the control from error occuring code to another to avoid the program termination.

Exception handling can be achieved by using keywords TRY, CATCH and CLEANUP. Exceptions can be occured at any point of time by a misplaced/wrong piece of code in the program.

To handle the exception, the problemetic code that causes the error should code under TRY block. All the exception handling code should be coded in between TRY and ENDTRY block.

Exception are basically two types and those are —

  • Exceptions raised during the program execution due to invalid calculations or invalid movements.
  • Exceptions created by the programmer based on the requirements.

Syntax —

TRY. 
     
*Write code block here which causes an exception
Code-that-causes-exception

CATCH [BEFORE UNWIND] EX_CLASS1.
      Catch-block-for-class EX_CLASS1. 
      
CATCH [BEFORE UNWIND] EX_CLASS2.  
      Catch-block-for-class EX_CLASS2.
		.
		.
		.
CATCH [BEFORE UNWIND] EX_CLASSn.  
      Catch-block-for-class EX_CLASSn.
CATCH cx_root.     
      Catch-block-for-of-all-kinds-of-exceptions.
CLEANUP [INTO oref].  
      Cleanup-block-to-restore-the-consistent-state.
ENDTRY.

  • TRY − The TRY block contains the problematic code that is expected to cause an exception. It may contain control structures and calls of procedures or other ABAP code.
  • CATCH – The CATCH block executes when the specified exception in CATCH statement matched to the exception occurred. The CATCH block contains the statements to handle the exception.
  • CLEANUP − The statements in the CLEANUP block are executed whenever an exception not caught by the handler of the same TRY … ENDTRY construct. Within the CLEANUP clause, the system can restore an object to a consistent state or release external resources.

How many parts in Exception Handling?

Exceptions handling have two parts and those are —

  • Raising the exception – This part used to identify the code that causes the exception and add the code to the TRY block.
  • Catching the exception – Handlers used to catch the exception. In this part, identify the type of the exception and we have to code with CATCH block to handle the exception.

Note!

  • Handlers should be defined for statements in a TRY block (TRY… ENDTRY).
  • Within the TRY ENDTRY, each handler is stated by a CATCH statement followed by the exception class.
  • The statements that causes the exception should code in between TRY and the first CATCH.
  • The statements following the CATCH clause are executed only if the handler catches an exception.
  • The CATCH block has no scope terminator and next CATCH statement or CLEANUP statement or ENDTRY act as scope terminators.
  • Each exception is caught only once by the first suitable handler.
  • Each handler can catch more than one type of exceptions based on the definition.
  • The sequence of handlers is more important.
  • If system cannot find an appropriate handler in a TRY … ENDTRY construct, it searches for handlers in the next outer TRY … ENDTRY construct. If it cannot find there, it continues the search upward in the call hierarchy.
  • Each TRY … ENDTRY construct contains a maximum of one CLEANUP clause.

Example —

Below example explains how the exception can be handled in ABAP programming. Program for multiplication two number with non-numeric exception handling.

Code —

*&---------------------------------------------------------------------*
*& Report  Z_EXCEPTION_HANDLING
*&---------------------------------------------------------------------*
*& Written by TutorialsCampus
*&---------------------------------------------------------------------*

REPORT  Z_EXCEPTION_HANDLING.

* Declaring variables
DATA: rslt TYPE p LENGTH 10,
      op_ref TYPE REF TO cx_root,
      msg_text TYPE string.

* Declaring parameters
PARAMETERS: inp1  TYPE c LENGTH 5,
            inp2  TYPE c LENGTH 5.

* Try block starting
TRY.

* Result calculation by multiplying both inputs inp1, inp2.
    rslt = inp1 * inp2.

* CATCH for cx_sy_conversion_no_number: Value for Attribute TEXTID
  CATCH cx_sy_conversion_no_number INTO op_ref.

* moving the error mssage msg_text from op_ref->get_text( )
    msg_text = op_ref->get_text( ).

* Default CATCH cx_root for any other exceptions.
  CATCH cx_root INTO op_ref.

* moving the error mssage msg_text from op_ref->get_text( ).
    msg_text = op_ref->get_text( ).

ENDTRY.

* Validating if any error occured.
IF NOT msg_text IS INITIAL.

* Displays only when error occured.
  WRITE / msg_text.

ELSE.

* Displays only when no error occured.
  WRITE: / 'Multiplication Result :', rslt.

ENDIF.

Output —

Case-1: Both inputs are valid and numeric
Exception handling example output
Exception handling example output1
Exception handling example output2

Case-2: Both inputs are not valid and non-numeric
Exception handling example output
Exception handling example output3
Exception handling example output4

Explaining Example —

In the above example, each and every statement is preceeded with a comment to explain about the statement. Go through them to get clear understanding of example code.

TRY…ENDTRY represents the try block. rslt = inp1 * inp2 is the code that expects to causes the exception. CATCH cx_sy_conversion_no_number INTO op_ref, used to catch the cx_sy_conversion_no_number exception into op_ref.

msg_text = op_ref->get_text( ), moving the error mssage msg_text from op_ref->get_text( ). CATCH cx_root INTO op_ref, used to catch any other exceptions. IF NOT msg_text IS INITIAL, verifies the msg_text is initial or not. If it is initial, displays the error from msg_text. Otherwise, multiplication result rslt.

Preface – This post is part of the ABAP Beginner series.

Introduction

A programmer always tries to code in such a way that his code is bug free and full proof. But there are certain scenarios, where his codes can fail. In such case, if the coder already knows the scenarios, then he handle them in form of Error handling. But, in case of situations, where an error can be generated due to unknown situations and left un-handled can cause serious dumps. For these scenarios, we have exception handling in SAP. In this article we will explore all scenarios of Exception and Error Handling in ABAP Reports

Exception and Error Handling in SAP ABAP Reports

As discussed above, a coder is required to handle known issues as well as intended error messages. These messages are shown to user in the output via MESSAGE statement.

Different ways to catch Errors/Exception

ABAP provides various ways to catch errors in an ABAP program.

  1. Using System Variable

The simplest way is to use their system variables.

 SY-SUBRC EQ  0. "This statement indicates that an operation completed successfully.
 SY-SUBRC NE  0. "This statement indicates that an operation has failed.

This way works directly if the entire code of report was process within the same program. It means, it cannot catch an error directly in case you have processed a Function Module or ABAP Class statements. For those entity, we need to raise exception from their end, and then exception can be handled in the report and processed accordingly.

  1. Catching Errors based on Exception

In case, we implement a function module or method of a class, then it is important to raise exception from these classes and then we can catch these exceptions in report and show respective error.

For Example:

CALL FUNCTION 'Test_Function'
     EXPORTING
          DELIMITER =   ':'
          STRING        =   lv_string
     IMPORTING
          HEAD           =   lv_head
          TAIL             =   lv_tail
     EXCEPTIONS
          NOT_FOUND   =  1
          OTHERS       =   2.


CASE SY-SUBRC.
     WHEN 1. ...
// Show Error Message
     WHEN 2. ...
// Show Error Message
     WHEN OTHER.
// Show Error Message
ENDCASE.
  1. Using TRY CATCH ENDTRY

In case an exception is raised via a method of class, or an unexpected exception is raised, in these cases, we use TRY CATCH functionality of SAP ABAP. This is one of the best full proof way to handle all types of exceptions.

Example:

TRY.
     //Call your class or function module here
CATCH CX_SY_ZERODIVIDE INTO O_REF. // The exception you have raised there
     MESSAGE “Your Error Message”.
ENDTRY.

Different ways to show Messages

  1. Using ABAP Statement

Syntax:

MESSAGE ‘<Enter Your Text here>’ TYPE ‘Enter the type of Message here’.

Types of Message

ABAP provides the following 6 types of messages:

Message Type Meaning Explanation
A Termination This message is shown during program termination.
E Error This message is shown during Error.
I Information This message is used to show any information.
S Success This shown in the status of the Output screen.
W Warning It behaves like an error message.
X Exit It causes a short dump with error message.
  1. Using Predefined Function Modules

ABAP provides following function modules that can be used to store, format and show messages altogether:

Function Module Usage
MESSAGES_INITIALIZE To Initialize the messages.
MESSAGE_STORE To Store the messages to be displayed.
MESSAGES_SHOW To Display all the messages together on a pop up
FORMAT_MESSAGE To Format the messages
HR_DISPLAY_ERROR_LIST To display all the error messages

Example:

  1. Using Message Statement
MESSAGE 'This is an error message' TYPE 'E'.
  1. Using Multiple functions to store and show messages:
" It is Initialized only initially...
* Initialize your messages
  CALL FUNCTION 'MESSAGES_INITIALIZE'
    EXCEPTIONS
      log_not_active       = 1
      wrong_identification = 2
      OTHERS               = 3.
"One by one append all your messages here
      PERFORM store_messages USING 'E'
                                   w_pn
                                   w_batch2
                                   w_werks
                                   ' '
                                   w_msgno.
FORM store_messages USING p_msgty
                          p_msgv1
                          p_msgv2
                          p_msgv3
                          p_msgv4
                          p_txtnr.
  IF p_msgty EQ 'E'.
    w_err_fg = 'X'.
  ENDIF.
* Store all your messages meant to be displayed
  CALL FUNCTION 'MESSAGE_STORE'
    EXPORTING
      arbgb                  = 'ZCCH001'
      msgty                  = p_msgty
      msgv1                  = p_msgv1
      msgv2                  = p_msgv2
      msgv3                  = p_msgv3
      msgv4                  = p_msgv4
      txtnr                  = p_txtnr
    EXCEPTIONS
      message_type_not_valid = 1
      not_active             = 2
      OTHERS                 = 3.
ENDFORM.                    " STORE_MESSAGES
"In the end fetch all your message and show them altogether
* This displays all the messages in a popup
  CALL FUNCTION 'MESSAGES_SHOW'
    EXPORTING
      show_linno         = ' '
    IMPORTING
      e_exit_command     = wa_exit_command
    EXCEPTIONS
      inconsistent_range = 1
      no_messages        = 2
      OTHERS             = 3.
  1. Using HR_DISPLAY_ERROR_LIST
DATA:
it_error        TYPE STANDARD TABLE OF HRERROR,"TABLES PARAM
wa_error     LIKE LINE OF it_error .
DATA(ld_no_popup) = 'some text here'.
DATA(ld_no_print) = 'some text here'.
DATA(ld_no_img) = 'some text here'.
DATA(ld_no_msgno) = 'some text here'.
DATA(ld_linesize) = '123 '.
DATA(ld_listheader) = 'Check type of data required'.
DATA(ld_colheader) = 'Check type of data required'.
DATA(ld_hidemsg) = 'some text here'.
 
 
"populate fields of struture and append to itab
append wa_error to it_error.
.
CALL FUNCTION 'HR_DISPLAY_ERROR_LIST'
* EXPORTING
*   no_popup =                   ld_no_popup
*   no_print =                   ld_no_print
*   no_img =                     ld_no_img
*   no_msgno =                   ld_no_msgno
*   linesize =                   ld_linesize
*   listheader =                 ld_listheader
*   colheader =                  ld_colheader
*   hidemsg =                    ld_hidemsg
* TABLES
*   error =                      it_error
  EXCEPTIONS
    INVALID_LINESIZE =           1
    .  "  HR_DISPLAY_ERROR_LIST
IF SY-SUBRC EQ 0.
  "All OK
ELSEIF SY-SUBRC EQ 1. "Exception
  "Add code for exception here
ENDIF.

imagesКогда мы создаем какой-либо многократно используемый компонент, например функциональный модуль или метод в классе, мы сталкиваемся с необходимостью обработки непредвиденных ситуаций (какой-либо входной параметр, оказался не заполненным или доступ к файлу не был получен и т.п.), т.е. тех ситуаций, после которых программа не может выполняться далее стандартным образом, либо требуется дополнительная обработка.

В приведенной статье рассматриваются способы вызова и обработки данных ситуаций, называемых исключениями.

В ABAP есть два основных способа работы с исключениями, классический способ заключается в вызове особых ситуаций описанных в ФМ или методе на отдельной закладке:

1

Классический способ может использоваться и в классах:

2

Новый способ основывается на ООП, где в качестве исключений используются классы (обратите внимание, что установлена галочка – классы исключений):

3

Хочется отметить, что новый способ был введен с версии SAP Web AS 6.10 и при создании новых функциональных модулей или методов рекомендуется использовать именно его. В данной статье не рассматриваются системные исключения и их обработка до введения классов исключений.

В RFC модулях в настоящее время используется классический способ обработки исключений. Не допускается одновременно использовать классический и основанный на классах, способы обработки исключений (в интерфейсе методов, процедур, функций).

Классический способ обработки исключений

При вызове исключения, системное поле sy-subrc будет заполнено номером, под которым исключение было обозначено при вызове ФМ, метода или процедуры:

CALL FUNCTION ...

...

EXCEPTIONS

  Ошибка1 = 1

  Ошибка2 = 2.

Как правило, исключения вызываются с текстом сообщения, данный текст может быть описан статически – при вызове исключения оператором MESSAGE, либо динамически – путём получения текста из описания ФМ.

Так же исключение может быть вызвано без какого-либо текста (оператором RAISE ИмяИсключения), но данный способ лучше не использовать, т.к. вызов исключения должен как-то себя расшифровывать и говорить о том, что собственно произошло.

Напишем небольшой ФМ, рассчитывающий сумму двух чисел, оба параметра помечены как необязательные, если первый параметр не будет задан при вызове ФМ, система выдаст исключение – no_num_1.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

FUNCTION ZTEST_EXC.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_NUM_1) TYPE  I OPTIONAL

*»     REFERENCE(I_NUM_2) TYPE  I OPTIONAL

*»  EXPORTING

*»     REFERENCE(E_SUMM) TYPE  I

*»  EXCEPTIONS

*»      NO_NUM_1

*»———————————————————————-

  IF i_num_1 IS NOT SUPPLIED.

    MESSAGE e398(00) WITH ‘Число 1 не указано, расчёт невозможен’ RAISING no_num_1.

  ENDIF.

  E_SUMM = i_num_1 + i_num_2.

ENDFUNCTION.

И программа для его вызова:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

DATA:

  gv_num_2 TYPE i VALUE 10,

  gv_summ  TYPE i.

CALL FUNCTION ‘ZTEST_EXC’

  EXPORTING

    i_num_2  = gv_num_2    » Число 2

  IMPORTING

    e_summ   = gv_summ     » Сумма

  EXCEPTIONS

    no_num_1 = 1

    others   = 2.

IF sysubrc <> 0.

MESSAGE ID symsgid TYPE symsgty NUMBER symsgno

            WITH symsgv1 symsgv2 symsgv3 symsgv4.

ENDIF.

WRITE gv_summ.

При запуске программы произойдет вызов исключения, т.к. был использован тип сообщения «Е», программа завершит свое выполнение после показа сообщения:

4

Замечу, что это вовсе не означает, что при вызове ФМ или метода и обработке исключения необходимо завершать работу программы, вы можете свободно продолжить её выполнение и далее, добавив например, сообщение об ошибке в лог программы, а не на вывод как в примере.

Ключевое слово OTHERS используется для того чтобы поймать исключения не описанные в ФМ или явно неуказанные, при вызове ФМ.

Пример вызова неописанного исключения:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

FUNCTION ztest_exc.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_NUM_1) TYPE  I OPTIONAL

*»     REFERENCE(I_NUM_2) TYPE  I OPTIONAL

*»  EXPORTING

*»     REFERENCE(E_SUMM) TYPE  I

*»  EXCEPTIONS

*»      NO_NUM_1

*»———————————————————————-

  IF i_num_1 IS NOT SUPPLIED.

    MESSAGE e398(00) WITH ‘Число 1 не указано, расчёт невозможен’ RAISING no_num_2.

  ENDIF.

  E_SUMM = i_num_1 + i_num_2.

ENDFUNCTION.

В данном примере вызывается неописанное в интерфейсе ФМ исключение – no_num_2, которое будет благополучно поймано с помощью ключевого слова OTHERS (системное поле sy-subrc примет значение равное 2).

Кроме того, можно не обрабатывать большой список всех возможных исключений описанных в ФМ, тогда в случае если такое исключение будет вызвано поле sy-subrc примет значение, указанное в OTHERS.

В ФМ, могут быть добавлены новые исключения и в случае, когда при вызове ФМ они не обработаны и не указано слово OTHERS программа упадет в дамп с ошибкой времени выполнения — RAISE_EXCEPTION. Отсюда вывод, ключевое слово OTHERS подставляем всегда, при вызове ФМ (метода или процедуры), когда мы точно не уверены в неизменности компонента.

5

При вызове исключения в процедурах (perform…) из ФМ, система пытается найти и вызвать исключение в первом ФМ из стека вызовов, если исключение не найдено, вызывается так же, как и неопределенное исключение в ФМ.

Как уже было упомянуто выше, есть возможность получать текст непосредственно из описания особой ситуации:

6

ФМ будет выглядеть следующим образом:

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

FUNCTION ztest_exc.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_NUM_1) TYPE  I OPTIONAL

*»     REFERENCE(I_NUM_2) TYPE  I OPTIONAL

*»  EXPORTING

*»     REFERENCE(E_SUMM) TYPE  I

*»  EXCEPTIONS

*»      NO_NUM_1

*»———————————————————————-

  DATA:

    lv_fun TYPE functfuncname,

    lv_exc TYPE functparameter,

    lv_txt TYPE swotlqshorttext.

  lv_fun = ‘ZTEST_EXC’.

  lv_exc = ‘NO_NUM_1’.

  CALL FUNCTION ‘SWO_TEXT_FUNCTION_EXCEPTION’

    EXPORTING

      language  = sylangu

      function  = lv_fun

      exception = lv_exc

    IMPORTING

      shorttext = lv_txt.

  IF i_num_1 IS NOT SUPPLIED.

    MESSAGE e398(00) WITH lv_txt RAISING no_num_1.

  ENDIF.

  e_summ = i_num_1 + i_num_2.

ENDFUNCTION.

Результат: 7

Иногда особые ситуации используются не как исключения, а как параметры показывающие обработку ФМ и его результат, возвращаемый в поле sy-subrc, хотя лучше бы пренебречь подобным стилем:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

FUNCTION ZMORE_THEN_10.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_VAL) TYPE  I

*»  EXCEPTIONS

*»      MORE_10

*»      LESS_10

*»      EQUAL_10

*»———————————————————————-

  IF i_val = 10.

    RAISE equal_10.

  ELSEIF i_val > 10.

    RAISE more_10.

  ELSE.

    RAISE less_10.

  ENDIF.

ENDFUNCTION.

Программа:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

DATA:

  gv_val TYPE i VALUE 10.

CALL FUNCTION ‘ZMORE_THEN_10’

  EXPORTING

    i_val    = gv_val

  EXCEPTIONS

    more_10  = 1

    less_10  = 2

    equal_10 = 3.

CASE sysubrc.

  WHEN 1.

    WRITE ‘More 10’.

  WHEN 2.

    WRITE ‘Less 10’.

  WHEN 3.

    WRITE ‘Equal

Результат:

8

Сообщения, вызываемые в ФМ или методах, оператором MESSAGE, без дополнения RAISING, либо сообщения вызываемые системой (например, при обработке экранов), могут быть обработаны программой с использованием дополнения: error_message = n_error, указываемого так же после ключевого слова EXCEPTIONS.

При обработке сообщений:

  • Сообщения с типом I, W, S не обрабатываются, но записываются в журнал обработки фонового выполнения, если происходит обработка в фоне.
  • Сообщения с типом E или A могут быть обработаны, при этом в поле sy-subrc будет записано значение n_error. При вызове сообщения с типом А, происходит вызов ROLLBACK WORK (см. описание оператора MESSAGE).
  • Сообщение с типом X не обрабатывается, программа завершается с дампом.

Пример ФМ:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

FUNCTION ztest_exc.

*»———————————————————————-

*»*»Локальный интерфейс:

*»  IMPORTING

*»     REFERENCE(I_NUM_1) TYPE  I OPTIONAL

*»     REFERENCE(I_NUM_2) TYPE  I OPTIONAL

*»  EXPORTING

*»     REFERENCE(E_SUMM) TYPE  I

*»  EXCEPTIONS

*»      NO_NUM_1

*»———————————————————————-

  IF i_num_1 IS NOT SUPPLIED.

    MESSAGE e398(00) WITH ‘Число 1 не указано, расчёт невозможен’.

  ENDIF.

  E_SUMM = i_num_1 + i_num_2.

ENDFUNCTION.

Программа:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

PROGRAM test_exceptions.

DATA:

  gv_val TYPE i VALUE 10,

  gv_summ TYPE i.

CALL FUNCTION ‘ZTEST_EXC’

  EXPORTING

    i_num_2  = gv_val    » Число 2

  IMPORTING

    e_summ   = gv_summ    » Сумма

  EXCEPTIONS

    error_message = 1

    others   = 2.

IF sysubrc = 1.

  WRITE ‘ФМ вызвал MESSAGE с типом E,A’.

ENDIF.

Результат:

9

Обработка исключения классическим способом может быть выполнена динамически, с помощью ключевого слова EXCEPTION-TABLE. Пример:

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

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

DATA: line     TYPE c LENGTH 80,

      text_tab LIKE STANDARD TABLE OF line,

      filename TYPE string,

       filetype TYPE c LENGTH 10,

      fleng    TYPE i.

DATA: func TYPE string,

      ptab TYPE abap_func_parmbind_tab,

      ptab_line TYPE abap_func_parmbind,

      etab TYPE abap_func_excpbind_tab,

      etab_line TYPE abap_func_excpbind.

func = ‘GUI_DOWNLOAD’.

filename = ‘c:temptext.txt’.

filetype = ‘ASC’.

ptab_linename = ‘FILENAME’.

ptab_linekind = abap_func_exporting.

GET REFERENCE OF filename INTO ptab_linevalue.

INSERT ptab_line INTO TABLE ptab.

ptab_linename = ‘FILETYPE’.

ptab_linekind = abap_func_exporting.

GET REFERENCE OF filetype INTO ptab_linevalue.

INSERT ptab_line INTO TABLE ptab.

ptab_linename = ‘DATA_TAB’.

ptab_linekind = abap_func_tables.

GET REFERENCE OF text_tab INTO ptab_linevalue.

INSERT ptab_line INTO TABLE ptab.

ptab_linename = ‘FILELENGTH’.

ptab_linekind = abap_func_importing.

GET REFERENCE OF fleng INTO ptab_linevalue.

INSERT ptab_line INTO TABLE ptab.

...

etab_linename = ‘OTHERS’.

etab_linevalue = 10.

INSERT etab_line INTO TABLE etab.

CALL FUNCTION func

  PARAMETERTABLE

  ptab

  EXCEPTIONTABLE

  etab.

CASE sysubrc.

  WHEN 1.

    ...

    ...

ENDCASE.

Обработка исключений, основанная на классах

Как понятно из названия, под исключениями в данном случае понимаются объекты специальных классов исключений. Вызов такого исключения может быть выполнен либо в программе с помощью оператора RAISE EXCEPTION, либо системой (например, при делении на ноль будет вызвано предопределённое исключение CX_SY_ZERODIVIDE, список таких исключений), либо через дополнение THROW в условных выражениях (с версии ABAP 7.4).

Во всех случаях инициируется создание объекта указанного класса (если указано дополнение INTO в CATCH), в атрибутах которого содержится информация о возникшей исключительной ситуации, доступ к ним, как правило, осуществляется через методы этого класса.

Классы особых ситуаций могут быть определены как локально, так и глобально через построитель классов – транзакция SE24, диалог создания:

10

В данном случае галочка «с классом сообщений» означает использование в качестве текста сообщения из класса сообщений транзакция SE91 (будет рассмотрено ниже). По умолчанию текст сообщения создается в текстах класса:

11

Категории исключений

Все классы особых ситуаций являются производными одного из классов: CX_NO_CHECK, CX_DYNAMIC_CHECK или CX_STATIC_CHECK, которые сами являются производными общего суперкласса CX_ROOT.

  • CX_STATIC_CHECK – как правило, исключения которые вызываются в процедуре (ФМ или методе), должны быть либо обработаны в ней, либо процедура должна иметь соответствующий интерфейс, чтобы вызывающий её код мог обработать эту ситуацию. Если исключение определено как потомок этого класса, оно должно быть явно указано в интерфейсе метода (ФМ или формы) в котором происходит его вызов. Данная категория используется тогда, когда в коде явно ожидается передача обработки особой ситуации на уровень выше того места где оно было вызвано. Если при статической проверке, система не увидит обработки в блоке TRY..CATCH..ENDTRY подобного исключения система выдаст предупреждение: 12
  • CX_DYNAMIC_CHECK – при проверке кода, компилятор не будет делать предупреждений об отсутствии обработки исключений их этой категории, в случае вызова исключения его обработка будет проверена динамически и если обработчик не будет найден программа упадет в дамп. Обычно данная категория используется тогда, когда исключение может быть обработано внутри самого метода, без передачи обработки выше по стеку. Примером такой категории может являться исключение вызываемое при делении на ноль, передавать его выше по стеку и указывать в интерфейсе метода вовсе не обязательно, т.к. мы можем его обработать внутри самого метода. Однако, если мы хотим передать обработку данного исключения, необходимо указать его в интерфейсе метода.
  • CX_NO_CHECK – аналогичны предыдущему типу, но данную категорию нельзя объявлять в интерфейсах, при этом классы исключений наследуемые от этого класса, неявно все же передаются в интерфейс и выше по стеку вызовов. Данную категорию следует использовать для исключительных ситуаций, которые могут произойти в любое время и не могут быть обработаны непосредственно в коде метода. Кроме того, можно использовать в случаях когда одна и та же исключительная ситуация может возникнуть во множествах методов, а объявлять её в интерфейсах каждого из методов не имеет смысла, т.к. это усложнит код. В итоге подобные исключения могут пройти всю цепочку вызовов методов (т.к. неявно передаются в интерфейс) и быть обработаны на уровне программы.

На исключения накладываются следующие ограничения:

  • Исключение не может быть объявлено в интерфейсе статического конструктора:

13

  • Исключение не может быть объявлено в интерфейсе обработчика событий. При этом если в коде обработчика произошел вызов исключения, и он не был обработан, система вызовет исключение — CX_SY_NO_HANDLER, которое может быть обработано в вызывающем его коде.
  • При вызове программ через SUMBIT или CALL TRANSACTION, исключение, возникающее в вызываемой программе, не может быть передано в вызывающую программу.

Небольшой пример с локальным классом исключения:

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

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

PROGRAM test_exceptions.

CLASS lcx_no_num DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcl_test_exceptions DEFINITION.

  PUBLIC SECTION.

    METHODS:

      do_summ IMPORTING

                i_num_1 TYPE i OPTIONAL

                i_num_2 TYPE i OPTIONAL

              RETURNING value(re_summ) TYPE int1

              RAISING lcx_no_num.

ENDCLASS.

CLASS lcl_test_exceptions IMPLEMENTATION.

  METHOD do_summ.

    IF i_num_1 IS NOT SUPPLIED OR i_num_2 IS NOT SUPPLIED.

      » Данное исключение присутствует в интерфейсе, может быть обработано вне метода

      RAISE EXCEPTION TYPE lcx_no_num.

    ENDIF.

    TRY.

      re_summ = i_num_1 + i_num_2.

      » Ошибка с дин. проверкой, при её обработке обнулим результат

    CATCH CX_SY_CONVERSION_OVERFLOW.

      re_summ = 0.

    ENDTRY.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test_exceptions TYPE REF TO lcl_test_exceptions,

  gv_summ TYPE int1.

START-OF-SELECTION.

  CREATE OBJECT go_test_exceptions.

  TRY.

    go_test_exceptions>do_summ(

      EXPORTING

        i_num_2 = 1

      RECEIVING

        re_summ = gv_summ

    ).

  CATCH lcx_no_num.

    WRITE ‘Не заполнены все параметры’.

  ENDTRY.

  go_test_exceptions>do_summ(

    EXPORTING

      i_num_1 = 999

      i_num_2 = 1

    RECEIVING

      re_summ = gv_summ

  ).

  WRITE: / ‘Результат cуммы 999 и 1:’, gv_summ.

В стандартной системе SAP имена всех классов особых ситуаций начинаются с CX_ , пользовательские исключения рекомендуется называть, начиная с ZCX или lcx для локальных классов исключений.

Класс CX_ROOT предоставляет некоторые предопределенные методы, которые наследуются всеми классами особых ситуаций:

  • Метод GET_SOURCE_POSITION возвращает имя главной программы и (если связаны) имена включенных программ (инклудов) и номер строки исходного кода, в которой возникла особая ситуация.
  • Метод GET_TEXT возвращает текст особой ситуации в форме строки.
  • Метод GET_LONGTEXT возвращает подробный текст текста особой ситуации в форме строки.

Тексты исключений

Каждому классу можно присвоить несколько текстов. Присвоенные им идентификаторы создаются построителем классов как константы в атрибутах класса. Тексты сохраняются в репозитарии текстов (OTR). Константы идентификаторы, представленные в шестнадцатеричном формате, уникальны на уровне системы:

14

Доступ к хранилищу текстов можно получить через транзакцию SOTR_EDIT.

В текстах можно определить параметры, их необходимо обозначить в амперсандах. В качестве примера, можно рассмотреть текст из класса исключения — CX_SY_FILE_IO:

15

В параметры будут переданы (при вызове метода GET_TEXT) соответствующие им атрибуты класса:

16

Заполняются эти атрибуты в конструкторе при вызове исключения:

DATA: lr_ex  TYPE REF TO cx_sy_file_io,

      lv_msg TYPE string.

TRY.

   ...

   RAISE EXCPETION TYPE cx_sy_file_io

      EXPORTING

         textid = cx_sy_file_io=>read_error

         filename = ‘somefile.txt’.

CATCH cx_sy_file_io INTO lr_ex.

   lv_msg = lr_ex>get_text( ).

   MESSAGE lv_msg TYPE ‘I’.

ENDTRY.

Так же в конструкторе можно указать, какой текст должен использоваться при инициировании особой ситуации, передав одну из определенных констант в параметр импорта TEXTID. Не рекомендуется использовать подобную методику, т.к. это может запутать код, однако как было уже показано выше SAP сам это использует (read_error, write_error в CX_SY_FILE_IO). Инкапсуляция текстов в классах сообщений и их саморасшифровываемость является одним из преимуществ над классическими исключениями.

Конструктор, который генерируется автоматически в SE24, для нового созданного исключения (ZCX_NO_NUM1), выглядит так:

CALL METHOD SUPER>CONSTRUCTOR

EXPORTING

TEXTID = TEXTID

PREVIOUS = PREVIOUS

.

IF textid IS INITIAL.

   me>textid = ZCX_NO_NUM1 .

ENDIF.

Блок обработки исключений

Особая ситуация может быть обработана, только если оператор, который может инициировать ее, заключен в блок TRY-ENDTRY. Затем особая ситуация обрабатывается с помощью оператора CATCH в блоке TRY-ENDTRY.

17

Блок TRY содержит набор операторов, обрабатывающих особые ситуации. Если в блоке TRY появляется особая ситуация, система осуществляет поиск первого оператора CATCH в том же блоке TRY-ENDTRY, а затем последовательно снаружи во всех заключающих блоках TRY-ENDTRY, обрабатывающих особую ситуацию. Если оператор находится, система осуществляет переход к его обработчику. Если обработчик найти не удается, но блок TRY-ENDTRY находится в процедуре, система осуществляет попытку передачи особой ситуации вызывающей программе.

Блок CATCH содержит обработчик особых ситуаций, исполняемый при возникновении указанной особой ситуации в связанном блоке TRY. Для оператора CATCH можно указать любое количество классов особых ситуаций. Таким образом, определяется обработчик особых ситуаций для всех этих классов особых ситуаций и их подклассов.

Блоки TRY-ENDTRY могут иметь вложенность любой глубины. Поэтому блок TRY, блоки CATCH и блок CLEANUP в целом сами могут содержать полные блоки TRY-ENDTRY.

При возникновении особой ситуации система осуществляет поиск по перечисленным обработчикам особых ситуаций в указанном порядке. Затем она исполняет первый обработчик особых ситуаций, оператор CATCH которого содержит подходящий класс особой ситуации или один из ее суперклассов.

Если ошибка не будет обработана и не будет передана вызывающей программе, система выдаст дамп с ошибкой времени выполнения — UNCAUGHT_EXCEPTION, в том случае когда не обрабатывается исключительная ситуация, связанная с ошибкой времени выполнения, система выдает дамп с ошибкой времени выполнения (например, CX_SY_CONVERSION_CODEPAGE — CONVT_CODEPAGE):

18

Просмотр ошибки в транзакции ST22:Безымянный

Распространение особых ситуаций

Если возникает особая ситуация (наследуемая от CX_DYNAMIC_CHECK, CX_STATIC_CHECK), она автоматически распространяется на все уровни стека вызовов, до тех пор, пока она не будет обработана или пока не встретится такой интерфейс, в котором она (либо её предки) будет отсутствовать.

Следующий пример демонстрирует распространение особой ситуации на несколько методов:

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

37

38

39

CLASS lcx_calc_error DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcx_summ_error DEFINITION INHERITING FROM lcx_calc_error.

ENDCLASS.

CLASS lcl_test_exc DEFINITION.

  PUBLIC SECTION.

  METHODS:

    do_calc

      RAISING

        lcx_calc_error,

    do_summ

      RAISING

        lcx_summ_error.

ENDCLASS.

CLASS lcl_test_exc IMPLEMENTATION.

  METHOD do_calc.

    do_summ( ).

  ENDMETHOD.

  METHOD do_summ.

    RAISE EXCEPTION TYPE lcx_summ_error.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test TYPE REF TO lcl_test_exc.

START-OF-SELECTION.

  CREATE OBJECT go_test.

  TRY.

    go_test>do_calc( ).

  CATCH lcx_calc_error.

    WRITE ‘Catched’.

  ENDTRY.

Обратите внимание на метод do_calc, в нем описана особая ситуация от которой наследуется lcx_summ_error, соответственно прерывание продолжится на следующий уровень и будет обработано в блоке TRY..CATCH..ENDTRY. При правильно выстроенной архитектуре наследования исключительных ситуаций, прозрачность кода заметно повышается.

В случае, когда используется исключение, наследуемое от CX_NO_CHECK, описание его в интерфейсе метода может быть опущено, т.к. оно инициируется неявным способом системой:

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

CLASS lcx_calc_error DEFINITION INHERITING FROM cx_no_check.

ENDCLASS.

CLASS lcx_summ_error DEFINITION INHERITING FROM lcx_calc_error.

ENDCLASS.

CLASS lcl_test_exc DEFINITION.

  PUBLIC SECTION.

  METHODS:

    do_calc,

    do_summ.

ENDCLASS.

CLASS lcl_test_exc IMPLEMENTATION.

  METHOD do_calc.

    do_summ( ).

  ENDMETHOD.

  METHOD do_summ.

    RAISE EXCEPTION TYPE lcx_summ_error.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test TYPE REF TO lcl_test_exc.

START-OF-SELECTION.

  CREATE OBJECT go_test.

  TRY.

    go_test>do_calc( ).

  CATCH lcx_calc_error.

    WRITE ‘Catched’.

  ENDTRY.

Очистка после вызовов исключений

Блок CLEANUP исполняется, когда выполнен выход из блока TRY-ENDTRY, так как система не смогла найти обработчик для исключения в определенном блоке TRY-ENDTRY, но особая ситуация обрабатывается в окружающем блоке TRY-ENDTRY или передается вызывающей программе.

Данный блок обычно применяется для освобождения занятых ресурсов: очистке ссылочных переменных, закрытие локаторов или наборов данных (datasets) и т.п. Допустим, Вы записываете некоторые данные в файл на сервере приложений. Внутри блока TRY Вы открываете набор данных (dataset) и начинаете запись в него. Однако в некоторый момент, случается особая ситуация, которую вы не обработали и блок TRY прерывает свою работу, при этом, не выполнив закрытие набора данных. Для того чтобы избежать подобной ситуации воспользуемся ключевым словом CLEANUP:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

TRY.

*  Открываем файл на запись:

   OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE

                        ENCODING DEFAULT.

*  Переносим данные в файл:

   LOOP AT lt_extract INTO ls_record.

      PERFORM sub_format_record CHANGING ls_record.

      TRANSFER ls_record TO lv_file.

   ENDLOOP.

*  Закрываем файл:

   CLOSE DATASET lv_file.

CATCH cx_sy_file_access_error INTO lr_file_ex.

*  Ошибки ввода, вывода (датасет в таком случае не открыт)…

CATCH lcx_format_error INTO lr_format_ex.

*  Обрабатываем свою внутренюю ошибку при форматировании…

*  при этом необходимо закрыть набор данных

   CLOSE DATASET lv_file.

CLEANUP.

*  В случае если возникнет не обработанное исключение закроем набор данных:

   CLOSE DATASET lv_file.

ENDTRY.

В случае возобновляемых оператором RESUME исключений, блок CLEANUP не выполняется. Блок CLEANUP, как и блок CATCH позволяет получить ссылочную переменную на вызванное исключение, с помощью дополнения [INTO oref].

Передача исключений по цепочке

Необходимо понимать, что особая ситуация может передаваться через любое количество иерархий вызова перед финальной обработкой. Одна особая ситуация может инициировать вторую и т. д. Каждая инстанция должна оставаться действительной, независимо то того, был ли связанный блок CATCH уже обработан или нет. Поэтому необходимо убедиться, что предыдущая инстанция особой ситуации доступна с помощью, по крайней мере, одной ссылки. Атрибут общей инстанции PREVIOUS, наследуемый всеми классами особых состояний из CX_ROOT, обеспечивает удобный для этого способ.

Пример:

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

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

CLASS lcx_very_big DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcx_calc_error DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcl_test_exceptions DEFINITION.

  PUBLIC SECTION.

    METHODS:

      do_calc IMPORTING

                i_num_1 TYPE i OPTIONAL

                i_num_2 TYPE i OPTIONAL

              RETURNING VALUE(re_result) TYPE i

              RAISING lcx_calc_error.

  PRIVATE SECTION.

    METHODS:

      do_summ IMPORTING

                i_num_1 TYPE i OPTIONAL

                i_num_2 TYPE i OPTIONAL

              RETURNING value(re_summ) TYPE i

              RAISING lcx_very_big.

ENDCLASS.

CLASS lcl_test_exceptions IMPLEMENTATION.

  METHOD do_summ.

    re_summ = i_num_1 + i_num_2.

    IF re_summ > 100.

      RAISE EXCEPTION TYPE lcx_very_big.

    ENDIF.

  ENDMETHOD.

  METHOD do_calc.

    DATA:

      lo_very_big TYPE REF TO lcx_very_big.

    TRY.

      me>do_summ(

        EXPORTING

          i_num_1 = i_num_1

          i_num_2 = i_num_2

        RECEIVING

          re_summ = re_result

      ).

    CATCH lcx_very_big INTO lo_very_big.

      RAISE EXCEPTION TYPE lcx_calc_error EXPORTING previous = lo_very_big.

    ENDTRY.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test_exceptions TYPE REF TO lcl_test_exceptions,

  gv_result TYPE i,

  go_calc_error TYPE REF TO lcx_calc_error,

  go_big_error  TYPE REF TO lcx_very_big.

START-OF-SELECTION.

  CREATE OBJECT go_test_exceptions.

  TRY.

    go_test_exceptions>do_calc(

      EXPORTING

        i_num_1   = 1000

        i_num_2   = 500

      RECEIVING

        re_result = gv_result

    ).

  CATCH lcx_calc_error INTO go_calc_error.

    go_big_error ?= go_calc_error>previous.

  ENDTRY.

Таким образом, пройдя по цепочке, мы всегда можем определить, в каком конкретном месте было инициировано исключение и что из-за этого произошло. Иногда при построении какой-либо ООП модели, удобно собрать всю цепочку из ошибок в каком-нибудь одном виде и выдать в качестве универсального исключения, в качестве примера рекомендую посмотреть этот пример.

Возобновляемые исключения и повтор блока TRY

При срабатывании исключения, выполнение программы в текущем контексте завершается. Иногда необходимо не завершать выполнение текущего контекста, для этого были созданы так называемые возобновляемые исключения. Для того чтобы вызвать такое исключение, необходимо в операторе RAISE (или в THROW) указать что вызывается именно возобновляемое исключение, при этом для того чтобы воспользоваться оператором RESUME (который возвращает код обратно в то место где было вызвано исключение), необходимо у оператора CATCH указать дополнение BEFORE UNWIND (обозначает обработку возобновляемого исключения), иначе система вызовет исключение CX_SY_ILLEGAL_HANDLER. При возврате в контекст, из которого было вызвано исключение блок CLEANUP не вызывается. Если в указанном в CATCH блоке не будет вызван оператор RESUME, контекст будет удален при выходе из блока CATCH.

Пример обработки возобновляемого исключения:

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

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

CLASS lcx_no_num DEFINITION INHERITING FROM cx_static_check.

ENDCLASS.

CLASS lcx_less_zero DEFINITION INHERITING FROM cx_no_check.

ENDCLASS.

CLASS lcl_test_exceptions DEFINITION.

  PUBLIC SECTION.

    METHODS:

      do_summ IMPORTING

                i_num_1 TYPE i OPTIONAL

                i_num_2 TYPE i OPTIONAL

              RETURNING value(re_summ) TYPE int1

              RAISING RESUMABLE(lcx_no_num).

ENDCLASS.

CLASS lcl_test_exceptions IMPLEMENTATION.

  METHOD do_summ.

    IF i_num_1 IS NOT SUPPLIED OR i_num_2 IS NOT SUPPLIED.

      » Данное исключение присутствует в интерфейсе, может быть обработано вне метода

      RAISE RESUMABLE EXCEPTION TYPE lcx_no_num.

    ENDIF.

    TRY.

      re_summ = i_num_1 + i_num_2.

      » Динамическая ошибка, при её обработке обнулим результат

    CATCH CX_SY_CONVERSION_OVERFLOW.

      re_summ = 0.

    ENDTRY.

  ENDMETHOD.

ENDCLASS.

DATA:

  go_test_exceptions TYPE REF TO lcl_test_exceptions,

  gv_summ TYPE int1.

START-OF-SELECTION.

  CREATE OBJECT go_test_exceptions.

  TRY.

    go_test_exceptions>do_summ(

      EXPORTING

        i_num_2 = 1

      RECEIVING

        re_summ = gv_summ

    ).

  CATCH BEFORE UNWIND lcx_no_num.

    RESUME.

  ENDTRY.

  WRITE: / ‘Cумма без указания 1-го числа’, gv_summ.

  go_test_exceptions>do_summ(

    EXPORTING

      i_num_1 = 999

      i_num_2 = 1

    RECEIVING

      re_summ = gv_summ

  ).

  WRITE: / ‘Результат cуммы 999 и 1:’, gv_summ.

При обработке исключений так же есть возможность повтора блока TRY..CATCH, делается это с использованием оператора RETRY. Пример:

PARAMETERS: number1 TYPE i,

            number2 TYPE i.

DATA result  TYPE p DECIMALS 2.

TRY.

    result = number1 / number2.

  CATCH cx_sy_zerodivide.

    number1 = 0.

    RETRY.

ENDTRY.

В данном случае если номер 2 будет равен нулю, система вызовет исключение, с помощью RETRY мы заново запустим блок TRY..CACTH, при этом уже исключение не возникнет, т.к. при делении нуля на ноль результатом будет ноль.

Отображение сообщений из классов сообщений в тексты исключений

Начиная с версии 6.40, появилась возможность связывать тексты исключительных сообщений с классами сообщений (транзакция SE91). Как уже упоминалось выше для этого необходимо в конструкторе класса, указать галочку класс сообщений. При этом вместо интерфейса IF_MESSAGE будет внедрен интерфейс IF_T100_MESSAGE (таблица T100 хранит в себе эти сообщения):

19

При редактировании текста, необходимо будет привязать его к классу и номеру сообщения, при этом заполнить параметры, если это необходимо:

20

Начиная с NW 2004, оператор MESSAGE позволяет напрямую обработку исключений, внедряющих интерфейс IF_T100_MESSAGE:

TRY.

   ...

CATCH cx_some_exception INTO lr_ex.

   MESSAGE lr_ex TYPE ‘E’.

ENDTRY.

Локальный класс исключения в приватном методе глобального класса

Бывают ситуации, когда для какого-либо приватного метода необходимо реализовать исключение, которое может быть вызвано исключительно данным методом (классом).  Реализовать подобное можно, если создать локальный класс исключений:

  • Перейти в локальные определения/внедрения:

21

  • Создать класс исключения:

22

  •  Указать в методе имя локального класса исключения (обязательно в режиме редактирования исходного кода):

23

Результат:

24

Если попробовать сделать тоже самое в режиме редактирования на основе формуляров, выскочит предупреждение о том, что такого класса не существует:

25

Более подробно об исключениях можно почитать в официальной документации:

http://help.sap.com/abapdocu_740/en/abenabap_exceptions.htm

ST22 ABAP programming errors

1) STORAGE_PARAMETERS_WRONG_SET


The problems with the dump STORAGE_PARAMETERS_WRONG_SET are mainly related to
the general restrictions of the 32bit OS. You can address up to 4GB of virtual
memory. Each process in OS is running in its own context and can address max.
4GB. the parameters which are related to ‘heap memory’ ie- abap/heap_area_dia,

abap/heap_area_nondia,

abap/heap_area_total

are should be set to 2 GB.
Common approaches which we can take for this dump are:

a) Please use in the ‘boot.ini’ file the switch
‘/3GB’ and restart your whole computer as described in the below SAP Notes:

SAP Note 552209 – Maximum memory utilization for
processes on NT/Win 2000
SAP Note 313347 – Windows NT, 2000, 2003: Editions and memory usage.

b) Another way to avoid this problem is to try
to add more criteria to your report/program/transaction so that there will be
fewer entries that need to be retrieved from your database or buffers. This
way, the system would not need to use up much resource to complete the
transaction. The query may have been quite big already and the load cannot be
accommodated. So please do add more criteria or options so that there will less
data to fetch.

c) To decrease the value of the parameters: rdisp/ROLL_SHM, rdisp/PG_SHM
d) Migrate to 64-bit OS (as per SAP Note 931024 and SAP Note 996600)


2)
 TSV_TNEW_PAGE_ALLOC_FAILED
The error TSV_NEW_PAGE_ALLOC_FAILED means that more memory was requested by the system
because the program needed to expand an internal table
, but not is available. When Extended
Memory is completely used up, the process will go into PRIV mode and it will start
using Heap Memory in case of Windows or vice versa in case of UNIX. Once
this enters into PRIV mode, no other user will be able to use the corresponding
work process. If there is enough memory for it to finish, you will not see the
error.

Roll area
extended memory area(EM)    
fixed storage space (HEAP)  
Short area
Paging area
Max address area
Please refer the following SAP notes:
SAP Note 649327 – Analysis of memory
consumption.
SAP Note 20527 — Runtime error TSV_TNEW_PAGE_ALLOC_FAILED
SAP Note 185185 – Application: Analysis of memory bottlenecks
SAP Note 369726 — TSV_TNEW_PAGE_ALLOC_FAILED

3)

 TSV_TNEW_OCCURS_NO_ROLL_MEMORY
The dump TSV_TNEW_BLOCKS_NO_ROLL_MEMORY usually
means that the roll buffer has been exhausted. Please check the usage of your
roll buffer with ST02->History->Page.
Near the bottom of the screen you can see ROLL BUFFER history. If the roll
buffer has been exhausted, you can increase the size with parameter rdisp/ROLL_MAXFS, but make sure you
have sufficient disk space to handle the additional size of this buffer if it
writes to disk.

Please refer the following SAP note:
SAP Note 185185 — Application: Analysis of
memory bottlenecks

4)

 LOAD_PROGRAM_LOST
The LOAD_PROGRAM_LOST error can occur when there are two or more versions of a given
program loaded into the buffer at any given time
. This happens when the program is changed by one user while it is still
in use by another user
. When a user gets to the program that is having
this problem and R/3 attempts to load the generated version from the buffer, it
sees that the version is not the most current and tries to swap it out for the
most current, but the load was lost from the PXA buffer, hence it throws the
dump of LOAD_PROGRAM_LOST.
LOAD_PROGRAM_LOST are the result of the combination of not enough PXA space +
changes of programs which are in use currently. A running program can’t run
with two different versions of one program. Ask the users restart their transactions (/nST22). By the way, if
the PXA would be big enough then the user who does not leave their transaction
for weeks will not see the changes to this application until they restart the
transaction.

Other way to correct the error is you need to run transaction SAMT & regenerate
the program(s)
that are listed in the dump. You can then do a $SYNC in the
command field in the affected application server, but make sure that the other
application servers are not running at that time. After the $SYNC, the other
app servers can be brought up and the buffers should then be in sync.

Please refer the following SAP notes:
SAP Note 5451 – LOAD_PROGRAM_LOST
SAP Note 24824 – Inconsistencies in a Program Load
SAP Note 10367 – Termination LOAD_PROGRAM_LOST


5
) CALL_FUNCTION_SIGNON_INCOMPL
The short dump CALL_FUNCTION_SIGNON_INCOMPL is
typical of an RFC-Call with incorrect or missing logon-data. So, we have to
find out where the call is coming from.

Please refer the following SAP notes:
SAP Note 171805 — Determining RFC client
when sign-on problems occur.
SAP Note 684788 — Possible reason for CALL_FUNCTION_SIGNON_INCOMPL.
SAP Note 901256 – Rabax “CALL_FUNCTION_SIGNON_INCOMPL”.

6)

 RFC_NO_AUTHORITY
This error mostly appears with the user SAPSYS.
The user SAPSYS is an internal user, it is not a personally used ID in the R/3
system. However, all system errors and ABAP programs are run via this user id.
As per note
 93254, since release 4.0 the parameter auth/rfc_authority_check is set on 1 per default. This means, as long as
you did not set it explicitly to value ‘0′, any incoming RFC call is checked as
described in the mentioned note.

The common approaches which we can take on this
dump are:

1. Deactivate RFC authority Check: set auth/rfc_authority_check to value ’0′ (zero) in your profile and restart
the server. (This is the least secure option as any authorization checks are
disabled for all RFC requests).

.
2. Assign full RFC authorities to the users who need to connect to your system
via RFC.
Please also check the user id provided in RFC connection (check from SM59)
which cause the dump RFC_NO_AUTHORITY. Make sure that this user has sufficient
authorizations.

Please refer the following SAP notes:
SAP Note 171805 – Determining RFC client when
sign-on problems
SAP Note 93254 — RFC short dump RFC_NO_AUTHORITY
SAP Note 91980 – Missing output of RFC short dump after login errors


7)
 SYSTEM_NO_TASK_STORAGE
For this error, please go to service market to
download the latest patch for your SAP Application release and apply the patch.
The latest patch would be useful for the problem. The SYSTEM_NO_TASK_STORAGE is
a known problem and related to limitation of 32bit OS. Please see notes 110172,
552209, 546361 for details. As long term solution you have to use 64bit Windows
(Note 996600).The cause for the dump SYSTEM_NO_TASK_STORAGE could also be an
old sap collector. SAP recommends using the updated collector version always.

The common approaches which we can take on this
dump are:

1. Check your settings match the recommendations
mentioned in SAP Note 146289.
2. Are limits set according to SAP Note 323816? (Referenced in SAP
Note 146289)
3. If there is no additional instances on same host then it should be possible
to increase EM/TOTAL_SIZE_MB from 4096 MB towards the RAM and even higher so
that ztta/roll_extension can be reached. Also the swap space should be set
according to SAP Note 153641 for this.

Please refer the following SAP notes:
SAP note 789477 – Large extended memory on AIX
(64-bit) as of Kernel
SAP note 191801 — AIX 64-bit with a lot of Extended Memory
SAP note 445533 — Lots of extended memory on AIX (64-bit)
SAP note 581319 — Signal 33 on AIX (64-bit only)
SAP note 153641 – Swap space requirement for R/3 64-bit kernel

8)

 CALL_FUNCTION_NOT_FOUND
The error CALL_FUNCTION_NOT_FOUND is due to the fact that the program called
the function which doesn’t exist in the library. Means the requested function
module is not found in table TFDIR. Also you may get this error if the buffered
version of the TFDIR contains errors. The error needs to attention based on the
function module. You may take a general approach mentioned in the SAP Note
98458.

Please refer the following SAP note:

Error causes:

(1) The function module does not exist (SE16
table=TFDIR)

(2) The buffered version of the TFDIR contains
errors.


SAP Note 98458 — SAPMSSY1,
CALL_FUNCTION_NOT_FOUND


9)
 CALL_FUNCTION_SINGLE_LOGIN_REJ
This error usually comes when you don’t have sufficient
authorization to login to the trusted system. This dump accompanies with 4
different error codes:

0 – Incorrect logon data for valid security ID.
1 – Calling system is not a Trusted System or security ID is invalid.
2 – Either user does not have RFC authorization (authorization object
S_RFCACL), or a logon was performed using one of the protected users DDIC or
SAP*.
3 – Time stamp of the logon data is invalid.

Please refer the following SAP notes:
Note 986707 – No authorization to log on as a
trusted system (RC=1)

SAP Note 128447 – Trusted/Trusting Systems
SAP Note 204039 – Authorization check in trusted system

10)

 SYSTEM_CORE_DUMPED
Generally, SYSTEM_CORE_DUMPED is related to R/3 system kernel. Upgrade the kernel patch to the latest may solve the issue. But
without a detail analysis of the core dump at the Kernel, we cannot conclude
the reason behind the dump. I would recommend contacting SAP for this dump.

SAP Note
19466
– Downloading SAP kernel
patches
11) PXA_NO_SHARED_MEMORY
In most situations where the ST22 DUMP
PXA_NO_SHARED_MEMORY occurs there is not enough contiguous address space to
create the buffer of size
xMB Approx (where x is size in mega bytes).
 
The SAP note 129813 may be relevant as some DLLs
may be positioned that are stopping the creation of this large buffer on
Windows platforms.

Also SAP note 307976 gives information about
this dump type PXA_NO_SHARED_MEMORY.
 


12)  Message_Type_X/RAISE_EXCEPTION … CNTL_ERROR
      
 Is a GUI related
error.
Go for latest GUI version to avoid this error.

How to check patch level of GUI-
àopen GUI-àF10-àabout SAP logon

You will get a File Version similar to:

7100.2.9.1039……7100 means SAPGUI 7.10……..2
means Compilation 2…….9 means Patch level…….1039 is a build number (it is of no
use for us)

Message_Type_X Dump also
occurs when proper date format is not maintained in SU01 transaction of the
user who have faced this dump. 

Incase you have received a complaint from
customer that he is receiving this dump while running some transactions, please
go to SU01 and check the date format in the defaults tab. If there is any date
format other than DD.MM.YYYY, please change that to this format to avoid this
error

13)   EXSORT_NOT_ENOUGH MEMORY
Memory bottleneck encountered by the program while sorting.

14)   SYSTEM_ROLL_IN_ERROR
Not enough memory for user context.

15)   SYSTEM_NO_MORE_PAGING
Not enough SAP Paging Memory. Set “rdisp/pg_maxfs
to sufficiently large value ( say 32,000
).
If the problem exists even after assigning this value then there could be
a fault in the program itself.

16)   SET_PARAMETER_MEMORY_OVERFLOW
Not enough memory for SET/GET Parameter (Otherwise known as SPA/GPA Memory
).Try extending the memory area with SAP profile “ztta/parameter_area”.

17)   SAPSQL_ARRAY_INSERT_DUPREC
Number range problem, likely document number exists.

18)   EXSORT_FWRITE_FAILED
Is related to disk space. There is not enough disk space for the external
sorting process in the sort directory. To avoid this move either the extract
files (DIR_EXTRACT) or the sort files (DIR_SORTTMP) to a separate directory
with enough space.

LOAD_PROGRAM_LOST:-  In most of
the case its not a big issue. Someone
has changed the source program when someone was using
it. Mostly
Development & Quality systems get this error. 

RABAX
SYSTEM_CANCELED
:- If an administrator
actively cancels a running transaction, this error is shown. In cases like
this, no error correction is required.

  
SYSTEM_CANCELED:- The program was not terminated due to an error, but
rather due to deliberately performed actions.

RAISE_EXCEPTION:- This error message you can see in lot of problems.
So it is hard to give solution. Most of the case will be with SAPGUI. Try to get latest version or patch of
SAPGUI
. You should also try to reinstall
Internet Explorer
on the affected workstation as GUI uses some components
of IE.  You must also load newest
Microsoft patches too
.

CNTL_ERROR:- This dump is due to a problem in the interaction
between R/3 and the workstation. Do the same things as in the case if
RAISE_EXCEPTION. Both are somewhat same kind of errors. CNTL_ERRORs are created
when a program attempts to do something with a GUI element in background. Since
the GUI is not available, the program raises an exception. If this transaction
/ screen / program was never intended to be run in background then there may
not be any handling for this exception. The CNTL_ERROR can also be caused by a
virus infection. Installing Microsoft’s latest patch(es) dealing with the this
viruses  can solve the problem.

TSV_TNEW_PAGE_ALLOC_FAILED:— This is a
buffer related error. This error comes when processing memory intensive
background jobs. Adjusting abap/heap
limit will solved the problem temporarily. Better to use dedicated apps server
for processing memory intensive background jobs. Parameters affecting this
error are : Ztta/roll_area ,
Abap/heap_area_total , Abap/heap_area_dia , Abap/heap_area_nondia
.

CALL_FUNCTION_SINGLE_LOGIN_REJ:— This dump is created if some authorizations for
S_RFC or S_RFCACL are missing. CALL_FUNCTION_SYSCALL_ONLY is another dump
related to this error.

MEMORY_NO_MORE_PAGING:- you can set the the value of paging. Set the value
of parameter rdisp/PG_MAXFS=300000. Also refer the note :- Note 133909 —
Maximum value for PG_MAXFS, PG_SHM, ROLL_MAXFS, ROLL_SHM.

19. OPEN_DATASET_NO_AUTHORITY

This
is an authorization issue.

Add
the authorization object S_DATASET to the user-id and give all the values
depending on your requirement. 

 

20. Dump UNCAUGHT_EXCEPTION — CX_SOCM_NOT_IMPLEMENTED

Please remove the following entries using SM30 to resolve the
short dump CX_SOCM_NOT_IMPLEMENTED.

View: TSOCM_COND_MAPP

Table entries:

SLMO SLMO0001 E0002 40 SYSTEM_ASSIGNMENT

SLMO SLMO0001 E0006 10 FREED_FROM_LOCKING

SLMO SLMO0001 E0007 10 MOPZ_LU_WITHDRAWN

SLMO SLMO0001 E0007 20 FREED_FROM_LOCKING

The entries are normally created due to implementation of IMG

Activity «Configuration of Extended Maintenance Optimizer
Functions».

22. MESSAGE TYPE
UNKNOWN
   I’m not sure about this

try implementing   notes548121,676245,321767,392649,411846,129238,215949,117852,155094,144536,305159,

425212,305159,605273,452513,64289,460254,202640,138886,508702,130022,119773,400859,336085,

78412,377910,126826,542666.

These
are all notes that are directly associated with this program and helped us with
issues in this process.

23. dynpro not found

this is a Z program, your
ABAPPER created a bug

24.
table invalid index
      I’m not sure about
this


->
SAP Note 1512979 (updated January 2011) contains the
correction you need to overcome this error. 

->Check Note 166487

->Re-process your 
BPC » application » can re-index automatically. There you choose
option index .

25. SYMPTOM: UNCAUGHT_EXCEPTION

An
UNCAUGHT_EXCEPTION ABAP dump is generated when loading data into the
target Info Provider. The text of the dump is:

«UNCAUGHT_EXCEPTION»
«CX_RSR_X_MESSAGE»
«SAPLRRMS» or «LRRMSU13»
«RRMS_X_MESSAGE»

Also the
I_IOBJNM = 0REQUEST
REPRODUCING THE ERROR:

This
erorr is caused when loading data into an InfoProvider. It could be a
DSO or InfoCube.

CAUSE:

The dump
is caused because the InfoObject 0REQUEST is not referenced to the
InfoObject 0REQUID. This can be checked in transaction RSD5. Compare the
delivered version with the active version in transaction RSD5. Instead
InfoObject 0REQUEST is most likely referenced to itself.

SOLUTION:

To solve
the problem ensure that SAP Note 1157796
is applied in the system and install the content version of 0REQUEST
again, following these steps from the Note: Transaction RSOR-> BI Content-> Object Types->
under InfoObjects select 0REQUEST
and transfer
it to the right
(note the following settings: «Only Necessary
Objects»; collection mode: «Collect Automatically»).

26.
UNCAUGHT_EXCEPTION CX_NWBC

ANS- deleted the
instance in rz04 and recreated

27.
objects_objref_not_assigned
cx_sy_ref_is_initial
     not sure

ANS- 1.

ANS 2. Increase the Background
processor

28. RPERF_ILLEGAL_STATEMENT

ANS-1

SE38 or SE80 ->Utilities → Settings → ABAP Editor → Debugging->classic Debugger   (try this)

When you switch from the new Debugger to the classic Debugger,
the system may reach ABAP code which the
classic Debugger cannot edit
. This
is ABAP code that is called directly
from the
kernel of the Web
application server
. This
concerns primarily conversion and field exits. If these kinds of modules are analyzed using the new Debugger, the
runtime error 
RPERF_ILLEGAL_STATEMENT is triggered whenever you change to the classic Debugger.

ANS 2-

Note
686710
— ABAP runtime error RPERF_ILLEGAL_STATEMENT

Note
675042
— RPERF_ILLEGAL_STATEMENT in asynchronous RFC

29. DATA_LENGTH_0 CX_SY_RANGE_OUT_OF_BOUNDS

ANS— Note-1167944

Понравилась статья? Поделить с друзьями:
  • Программная работа над ошибками кроссворд
  • Программная работа над ошибками 8 букв сканворд
  • Программная ошибка первичные и вторичные ошибки
  • Программная ошибка книга
  • Программная ошибка биос