Skip to Content

Exception handling in gateway projects

One of the most common requirements for any project is to have a proper exception handling framework. Same goes for any NetWeaver Gateway projects as well.

In this blog, I would elaborate on a basic yet powerful exception handling mechanism which we followed in one of our projects and which assisted primarily in quickly pin-pointing source code where dumps and other issues occurred.

I will leverage the concepts of Dynamic(CX_DYNAMIC_CHECK) and Static(CX_STATIC_CHECK) Exceptions.

Dynamic exceptions are those exceptions which if not declared in FM interface or class methods then they will not be checked during design time. They will not raise any SCI/ATC warning or error.

Static exceptions are those exceptions which if not declared in FM interface or class method and not caught will result into run-time error with full stack trace in transaction ST22. They also raise SCI/ATC warning or error.

How to leverage these age-old concepts with our SAPUI5 applications.

For our solution, I have created two types of exception classes – One which inherits from CX_STATIC_CHECK and another from CX_DYNAMIC_CHECK.

The trick lies in the implementation in the oData classes (DPC_EXT). Here we catch the custom exception (inherited from Static Exception Class) and raise another custom exception (inherited from Dynamic Exception Class) chaining the custom static exception.

This leads to following benefits.

  1. In case of exception full stack trace is logged in ST22.
  2. With static exceptions in place, no SCI/ATC error/warnings are bypassed.

Steps are illustrated below.

Step1: Creation of two exception classes

Figure 1: Custom exception class inheriting from static exception

Figure 2: Custom exception class inheriting from dynamic exception

Step2: Implementation of Static Exception Class in classes other than oData classes

Everywhere in the application I have raised and used an exception inheriting from static exception so that it is handled properly in application code. An example below –

Figure 3: Custom static exception used in Business Layer classes

Step3: Type Casting the static exception to dynamic one and raising same in oData classes

Figure 4: Custom dynamic exception used in oData implementation classes

Hoping this blog is useful for quite a few of you and your suggestions are much appreciated.

 

5 Comments
You must be Logged on to comment or reply to a post.
  • Hi Ankit.

    Why aren’t you chaining your custom exceptions, like ZCX_HR_LEAVE_REQ with the help of the parameter previous of /IWBEP/CX_MGW_BUSI_EXCEPTION or /IWBEP/CX_MGW_TECH_EXCEPTION?

    Then you don’t get your SCI/ATC checks failing, and you adhere to the convention of the OData framework as SAP designed it.

    I believe that exceptions of type /IWBEP/CX_MGW_…_EXCEPTION are also automatically logged with /n/IWBEP/ERROR_LOG or /n/IWFND/ERROR_LOG respectively, which would be a benefit.

    Best regards,
    André

     

    • Hello Andre,

      Thanks for feedback.

      As these errors are usually the business validations or database processing errors and have nothing to do with thw gateway errors so I wanted to log them with full stack trace in ST22. Also, we had hub deployment in our project and it becomes a task to check the gateway logs specifically for non gateway errors.

      Nonetheless, I feel your suggestion suits well in case of embedded deployment where same user can check all the erros in same system.

      Further, I wanted to explore and realize these old exception handling concepts in gateway projects.

      Thanks again.

       

  • The approach explained above focuses on tracking and tracing backend exceptions. This has no major impact on the message received by the fiori user.

    Certain errors which are purely backend processing(like field symbol not assigned, object not instantiated, etc.)  or business logic related in that case I am raising the errors as described above and on fiori application it will give an Internal server error message(not much descriptive and helpful).

    In case, I want to raise specific messages like ‘ETag failed, User <dummy> is locked’ etc. which does not fit the current business process as such but is technically acceptable, I just read the message and populate them in the message container and raise suitable exception of gateway(business – /IWBEP/CX_MGW_BUSI_EXCEPTION or technical – /IWBEP/CX_MGW_TECH_EXCEPTION). Such messages are more verbose and meaningful.

     

  • Dear Ankit Maskara,

    as useful as this blog is, there are some misleading info I am going to point out.

    Firstly, your suggestions really does the trick of full stack trace in st22. So yes, you have fulfilled your goal. On the other hand, st22 represent ABAP runtime errors -> therefore you have just designed and implemented a runtime error. That is not the ideal way to accomplish logging or debugging process.

    Secondly, your saying: “Dynamic exceptions are those exceptions which if not declared in FM interface or class methods then they will not be checked during design time” is misleading. First half is wrong, second is right. ABAP runtime enviroment needs to have dynamic exceptions registered in signature of the method in order to propagate it correctly. In fact, dynamic exceptions are processed exactly the same way as static exceptions during the runtime. If you try to raise static or dynamic exception in method, then the covariant-type of given exception must be registered in the signature. If not, than ABAP runtime threat this as a violation and another exception CX_SY_NO_HANDLER is raised that inherits from (cx_no_check). This behavior end up in dump, as neither you, neither SAP in it ODATA framework does not catch this exception and ST22 entry is created.

    So the difference between cx_static and cx_dynamic is not in in design time, nor in runtime. CX_STATIC_CHECK doesn’t mean much more, than the fact that checks are executed during the syntax check. Exception must either be registered in the method signature, or it must be handled within the scope(within the method). For CX_DYNAMIC_CHECK, neither of these checks are performed, but behavior in runtime is the same-> CX_SY_NO_HANDLER is raised.

    br,
    Boris