DOH Error Handling

Posted by Darren Parr on 25-Mar-2020 15:36

Hi

Some of our DOH requests are throwing custom errors back We need to serialise those custom errors into their native object and return them on the response. Essentially we have a message object which is built on top of apperror with extra properties.

is there any strategic location in the doh code which would allow me to do this?

I'm loathed to add error handling to each DOH endpoint as I prefer to catch our errors in a generic way.

Regards

Darren 

All Replies

Posted by Peter Judge on 25-Mar-2020 17:14

There's an OperationError event fired, that's intended for this kind of stuff.
 
The DOH events are static events, so you can subscribe once in a session and have everything flow through a single handler(s). There's an example event handler at  github.com/.../DOHEventHandler.cls , which doesn't contain the OperationError event but should be easy enough to follow. I would add the 'run' of this to your session startup.p.  
 
You can check the HandlerErrorEventArgs for the error raised: in 11.7.5+, use the OperationError property. Prior to that, the Error property has the previously-thrown error. (This new property was added because we needed a way to distinguish between the error being processed - the "data" for the event handler - and any errors that might be raised in the event handler).
 
 
 
 

Posted by Darren Parr on 25-Mar-2020 17:41

Thanks Peter. After looking more closely at it, I think there's perhaps another way but I could be wrong on this and so I'll ask you.

The DOH is just using the standard Write() method of the EntityWriter. This has a special case for errors which I think is where my issue lies. In my webhandler (non DOH requests) I catch any error and just assign my error object to poReposne:Entity. This works fine.

With the DOH requests, the DOH is passing this error object to the entity writer and it calls writeError if its a progress.lang.error. I've not had to try to override this before but I've seen some of your other stuff on extending the jsonentitywriter but to be honest what I've done so far hasn't worked.

I've added to the registry in the handlerequest call. Cant I just write it to the entity in here or do I have to write a full blown json dump with byte counts to make this all work.

.

Posted by Peter Judge on 25-Mar-2020 18:42

>The DOH is passing this to the entity writer and it calls writeError if its a progress.lang.error. I've not had to try to override this before but I've seen some of your other stuff on extending the jsonentitywriter >but to be honest what I've done so far hasn't worked.

It takles a couple of steps more than it should, because the JsonEntityWriter's WriteError() method is currently private (not protected). Instead of writing a MyJsonWriter that extend JsonEntityWriter, and overriding the WriteError method, you have to write a MyJsonWriter that uses the JsonEntityWriter, except for errors.

Something like

Class MyJsonWriter inherits MessageWriter:

   Def private property mJsonWriter as JsonEntityWriter.

Method protected void WriteError(pError as Progress.Lang.Error):

End.

   Method public void  Write(pData as Progress.Lang.Object).

     If valid-object(pData) and type-of(pData, P.L.Error) then Do:

            WriteError(cast(pData, P.L.Error)).

    Else

        mJsonWriter:Write(pdata).

  End method

End.

 
 
 

Posted by Peter Judge on 25-Mar-2020 18:48

(sorry, that other one got sent by mistake)
 

>The DOH is passing this to the entity writer and it calls writeError if its a progress.lang.error. I've not had to try to override this before but I've seen some of your other stuff on extending the jsonentitywriter >but to be honest what I've done so far hasn't worked.

It takles a couple of steps more than it should, because the JsonEntityWriter's WriteError() method is currently private (not protected). Instead of writing a MyJsonWriter that extend JsonEntityWriter, and overriding the WriteError method, you have to write a MyJsonWriter that uses the JsonEntityWriter, except for errors.

Something like this should work, but it's a little clunky

class MyJsonWriter inherits MessageWriter:
       def private property mJsonWriter as JsonEntityWriter.
      
       // appropriate constructors left out
      
       method protected void WriteError(pError as Progress.Lang.Error):
              // your implementation here
       end method.
      
    method public void  Write(pData as Progress.Lang.Object).
       if valid-object(pData) and type-of(pData, P.L.Error) then
            WriteError(cast(pData, P.L.Error)).
              else
              do:
                  mJsonWriter:Write(pdata).
                  assign this-object:entity = mJsonWriter:entity.
              end.
  end method.
end class.
 
 
Alternatively, if you build a JsonObject or JsonArray in the OperationErrorHandler, you can simply assign it to the response's Entity and things should work fine.
 
The main difference is one of scope, I think. The EntityWriters apply to all webhandlers and to the HTTP client too. The handler will apply only to DOH requests.
 
 
 
 
 
 

This thread is closed