How to Cancel Request from Within DOH Invoking Handler

Posted by jts-law on 18-Oct-2017 15:27

Hi All,

The backend to my KUIB app is a REST (WEB transport) service (Progress 11.7.1).  As part of the backend I have an event handler class that subscribes to the DataObjectHandler:Invoking events.  The Invoking handler is used to do some pre-processing before performing the actual REST requests.  My issue is that I can't figure out how to gracefully generate an error within the Invoking handler and return it to the client without continuing to process the request. 

I received the example below to get started with my Invoking handler.  From this example it appears that I should be able to set poEventArgs:Cancel, but this isn't working.  I can't find any documentation on the Cancel property, and when the Cancel property is set, the request just continues on processing.  Generating a new AppError stops the request processing, but it doesn't return the error message back to the client.

What I would like to do is cancel the request and return an error message(s) in the response, and then have my KUIB app display the error(s).

    /* Event published before the business logic function is called by the handler
       
       @param Progress.Lang.Object The handler publishing the event
       @param OperationInvocationEventArgs Event args for this event */
    method public void InvokingHandler (input poSender as Progress.Lang.Object,
                                        input poEventArgs as OperationInvocationEventArgs):
        define variable httpHeader as HttpHeader no-undo.
        
        httpHeader = poEventArgs:Request:GetHeader('SOMEHEADERVALUE').
        
        if httpHeader:Value eq 'go-away' then
            poEventArgs:Cancel = true. 
            
        
        if httpHeader:Value eq 'whoops' then
            poEventArgs:Error = new AppError('Error with credentials', 0).
            
    end method. 


Louis

All Replies

Posted by Peter Judge on 18-Oct-2017 16:10

In 11.7.1 we ignore the Cancel flag (for most events, it looks like). That has been changed in 11.7.2 where setting Cancel to true will cause an error to be raised. Setting the Error property to an error instance will do the same.
 
Reading your question, I can’t help but wonder whether this is the correct behavior  for Cancel (and also what the correct behavior might be).
 

Posted by jts-law on 18-Oct-2017 16:23

Thanks Peter.  Regarding using Cancel, Error, or some other method, I'm definitely open to suggestions.  Since I'm handling the connections to the proper domain in this Invoking handler, I think this is where I want to be able to stop processing if the user doesn't have access to the requested URI.

Since posting this question I have been playing around with it trying to get a response returned and this is what I have come up with.  I'm thinking the json will need to be tweaked as I'm not exactly sure what KUIB will be expecting.  Based on your comments, I could remove the Cancel property and just go with the Error.

Thoughts/suggestions?

jsonArry  = NEW JsonArray().
         jsonData  = NEW JsonObject().
         jsonData2 = NEW JsonObject().
         jsonData:Add("_retVal", "").
         jsonData2:Add("message", "Unauthorized access").
         jsonArry:Add(jsonData2).
         jsonData:Add("_errors", jsonArry).
         jsonData:Write(lcResp, TRUE).

         poEventArgs:Cancel                 = TRUE.
         poEventArgs:Response:StatusCode    = 400.
         poEventArgs:Response:StatusReason  = "Unauthorized access".
         poEventArgs:Response:ContentType   = "application/json".
         poEventArgs:Response:ContentLength = LENGTH(lcResp).
         oWriter = NEW WebResponseWriter(poEventArgs:Response).
         oWriter:Open().
         oWriter:Write(lcResp).
         oWriter:Close().

         poEventArgs:Error = NEW AppError(cStat + " " + cContactMsg, 400).
         
         RETURN.

The result is:

{
    "_retVal": "",
    "_errors": [
        {
            "message": "Unauthorized access"
        }
    ]
}

Posted by Peter Judge on 19-Oct-2017 08:28

I’m still thinking about what good /useful behavior for Cancel would be – especially what happens after the code says “Cancel”. (so should we return an error? Should we return what’s in the Response already? Just stop and assume you’ve done it all? Or something else – there is an OperationError event; I’m thinking that there could be an OperationCancel to give you control of that).
 
Regardless of that though …
 
- You should be able to just set the value of the Error property to an instance of a (say) AppError. The DOH’s HandleException method will take care of turning it into JSON or whatever.
- You cannot set the StatusResponse in code at the moment (the DOH does it already and I believe that PASOE doesn’t pass it along either) , so don’t bother with that.
- You should NOT use the WebResponseWriter yourself, the DOH will call it later and you may see odd messages in your logs (or weird double-headered responses in your client).
 

Posted by Peter Judge on 19-Oct-2017 08:37

I've logged issue PSC00361552 (Fix/define Cancel behaviour for DOH) for this issue. If you want to be added to the list of customers who need this fix, please contact Tech Support.

Posted by jts-law on 19-Oct-2017 08:49

Peter,

When I don't set the StatusCode, the response status always returns 500.  Also, I tried commenting everything out except for setting Error to a new AppError and the following is what is returned:

This is the only code executing:

poEventArgs:Error = NEW AppError("Unauthorized access", 400).

This is what the client receives in the body, and I don't see my error text in any header values either, and the status is 500 on this response.  I also noticed that when the responsewriter is used, the response is returned right away, using just the AppError causes the response to take just over 2 seconds which makes me think it's timing out.

{
    "_retVal": "",
    "_errors": []
}

I need to be able to return the error details to the client.  Do I need to use json in the AppError?

Louis

This thread is closed