Asynchronous appserver call exception handling

Posted by willer on 01-Jun-2016 01:31

Hello,

when executing an asynchronous procedure on the appserver and the appserver gives back an exception :"RETURN ERROR MyException." .

How can I catch this exception in the callback procedure on the client side?
When using synchronous call it works with a catch block.

Regards

Peter

All Replies

Posted by jbijker on 01-Jun-2016 02:33

Hi Peter

When doing an asynchronous call (applies to appserver & web service call) you need to save the asynchronous request handle and specify an event procedure, something like:

 RUN MyProcedure IN ServerHandle

   ASYNCHRONOUS SET hRequestHandle

   EVENT-PROCEDURE MyEventProcedure IN TARGET-PROCEDURE

  (...all the parameters you need, input & output - although output will not be set at this stage...)

   NO-ERROR.

Do your normal error checking here to catch any errors while trying to make the call.

Now for the event procedure. In this example we expect it to return a character variable back, change it to whatever you need. You don't need to specify any input parameters. When it runs this procedure ERROR-STATUS:ERROR and RETURN-VALUE will be set, so we need to preserve it in global variables which will be used later.

PROCEDURE MyEventProcedure:

 DEFINE INPUT  PARAMETER ipcResult AS CHARACTER   NO-UNDO.

 glErrorStatus = ERROR-STATUS:ERROR.

 gcReturnValue = RETURN-VALUE(1).

 gcResult = ipcResult.

END PROCEDURE.

Then you need to wait for this request to complete. Below I simply wait (plus timeout if it exceeds a specific time). Whenever the event procedure was run

 DO ON ERROR UNDO, THROW:

   ASSIGN giEtimeNow = ETIME.

   DO WHILE TRUE:

     PROCESS EVENTS.

     IF hRequestHandle:COMPLETE THEN

       LEAVE.

     IF ETIME > giEtimeNow + giAsyncTimeout THEN

     DO:

       hRequestHandle:CANCEL-REQUESTS().

       PROCESS EVENTS.

       RETURN ERROR "Asynchronous request timeout.".

     END.

   END.

   /* when it hits this it means the procedure completed and we should be able to use our global variables to see if it completed successfully */

   IF glErrorStatus THEN

     .. do your error handling here ...

   FINALLY:

     IF VALID-HANDLE(hRequestHandle) THEN

       DELETE OBJECT hRequestHandle.

   END FINALLY.

 END.

Hope this helps.

Regards

Johan

Posted by Laura Stern on 01-Jun-2016 08:05

What Johan said is the right idea, but not quite correct.  In the event procedure you wouldn't look at ERROR-STATUS:ERROR.  You would look at the attributes of the Async request handle associated with the RUN.  That is always available as the SELF handle that is set for you by the AVM when in the handler for a PROCEDURE-COMPLETE event.  Or you could use hRequestHandle if it is still in scope.  Often it isn't, thus the need for SELF.  So you would look at SELF:ERROR or SELF:STOP, for example.

I also wanted to point out that waiting for the response using PROCESS EVENTS is not very efficient.  You can do "WAIT-FOR PROCEDURE-COMPLETE of hRequestHandle" instead.  The "Pause n" phrase can be used if you want it to time out.  Though normally, you would do this in a GUI app where you are in a WAIT-FOR anyway.  Then the normal event processing is going on for the user, but when the AppServer procedure completes, your MyEventProcedure will run.  

Posted by jbijker on 01-Jun-2016 08:49

Thanks Laura, learning new stuff every day!

This thread is closed