The topic of the blog may seem queer but as I would illustrate later it is very relevant in the lives of technical consultants. I would illustrate with examples how these approaches would help you succeed or if fail then fail gracefully ( read exception and dumps ) . Lets look into each of one at a time.
- For e.g. if you want to do something like this then this a recipe for sure shot disaster. If lv_entity is not bound then you would run into a dump/exception.You can use this in possibly many ways and you should use this as much as possible.
lv_bo ?= lv_entity. lv_bo->set_property( iv_attr_name = ‘CITY’ iv_value = ‘Walldorf’ ).
the better way to the similar coding would be
lv_bo ?= lv_entity. CHECK lv_bo is bound. lv_bo->set_property( iv_attr_name = ‘CITY’ iv_value = ‘Walldorf’ ).
lv_bo ?= lv_entity. if lv_bo is bound. lv_bo->set_property( iv_attr_name = ‘CITY’ iv_value = ‘Walldorf’ ). endif.
This is a very common failure scenario and is so common that we often tend to ignore this.
- The second variety is when you write a new method/form etc. , then check whether the importing parameters are proper. This would mean if you expect a reference variable to be passed then it should be bound or if you have a mandatory parameter passed then it should be having some value. Similarly pass export only those parameters which are requested. ( This is not a disastrous case but can save performance).For e.g. if you are sending a collection as an importing parameter to a method then you can write the following statement. This way you know that the col is bound and contains entities
CHECK ir_col is bound and ir_col->size( ) > 0.
This one is my personal favorite. Often uncleared variable could cause embarrassing problems and of magnitude you cannot even imagine. For e.g. you are in a conditional statement where you fill some variables based on condition being true and condition was false and since the variable were not cleared you still get data in variables. Or for e.g. you failed to clear an entity reference variable it would cause you lots of issues. I am providing some examples
lv_bo ?= lv_person. lv_*** = lv_bo->get_property( ‘***’ ). “Key code if lv_person->get_parent( ) is not initial. lv_bo ?= lv_person->get_parent( ). lv_*** = lv_bo->get_property( ‘***’ ). “Key code ENDWHILE.
Now if the if condition is not true , then lv_*** is line no 5 should be blank but it would be filled with value fetched in line no 2. In this case it may not seem disastrous but in some cases it is extremely catastrophic.
The better way to do this would be following. As a general rule for methods which have returning or exporting parameters , clear the variables which are collecting values.
lv_bo ?= lv_person. clear lv_***. lv_*** = lv_bo->get_property( ‘***’ ). “Key code if lv_person->get_parent( ) is not initial. lv_bo ?= lv_person->get_parent( ). clear lv_***. lv_*** = lv_bo->get_property( ‘***’ ). “Key code ENDWHILE.
In my case , I was trying to create multiple DOCFLOW entities but I not have cleared the variable through which I was passing the data to docflow and I was passing the same docflow instance every time hence the data was getting overwritten in same entity.
Another of my personal favorite. Exceptions are pretty common while we execute a scenario in WebUI. But they are handled in the framework and hence even though exceptions are raised , gracefully WebUI screen opens. If I call a method and it runs into an exception , then it could result in a dump or exception. Both of them are not appreciated by the users hence it makes a lot of sense to fail gracefully and provide exception handling. As a general rule if you are coding in WebUI , don't raise exceptions and don't fail to catch exceptions. Both of them are absolutely necessary.
while lr_current_entity is not initial and lr_entity is not initial . * Add the entitiy try. Clear lr_entity. CHECK lr_ent is bound. lr_ent ?= lr_entity. if lr_ent->alive( ) = abap_true. Clear lr_adminh , clear lv_object_type. lr_adminh ?= lr_ent->get_related_entity( 'BTOrderHeader' ). if (Your_Condition). else. lr_current_entity ?= lr_iterator->get_next( ). lr_entity ?= ir_valuehelp_collection->get_next( ). endif. endif. catch cx_root. lr_current_entity ?= lr_iterator->get_next( ). lr_entity ?= ir_valuehelp_collection->get_next( ). endtry. endwhile.
Now this code serves two purposes
a) It handles the exception hence there would not be any disruption in WebUI.
b) In case of exception occurs , there is a handling in that case.
Some of these guidelines may appear didactic but in reality they help in avoiding embarrassing code mishaps.