Web Service return error if invalid request

Forums for specific tips, techniques and example code
User avatar
justin
Posts: 7
Joined: Tue Apr 22, 2014 1:22 pm
Location: Nelson, New Zealand

Web Service return error if invalid request

Postby justin » Tue Apr 22, 2014 1:58 pm

I am tring to implement a webservice in Jade (7), and have a requirement to allow/deny the incoming client request based on IP address. I have created a base class which all my webservices will inherit, as I only want to write this code in one place. I have overriden the processRequest method in the parent class, with the following code

Code: Select all

processRequest() updating, protected; vars ip_address : String; consumerValid : Boolean; begin ip_address := getServerVariable('REMOTE_ADDR'); consumerValid := getConsumer(ip_address); if not consumerValid then setError(23,"Unknown consumer","Unknown consumer"); endif; inheritMethod(); end;
Assume that the method getConsumer simply checks a stored list of ip address that are allowed, and returns true if there is an entry for the supplied IP address. The intention of this code was that the call would not progress at all unless the IP address was registered (At this stage a manual separate process). The issue that I am having is that the setError in the parent class, does not stop the executing at all, and for all intensive purposes is actually not doing anything. It seems to only work if implemented directly in the called method, which seems a bit of a pain as then I would have to add this code (or a call to a method with this code) to every webservice method.

This example is only one thing I am checking for, I also have some SOAP headers that contain additional information that I need to check, and again I would like to check all the required data before calling the actual webservice method. Now I have the SOAP header working fine, but that entails overriding the processRequestPostHeaders method, which is fine, but again even if I call setError it still quite happily continues to the actual web method, seemingly oblivious to the attempt to circumvent the process.

I had some success in overriding reply(), and only calling return inheritMethod() when all my checks were successfully done, but again setError did not work, and it appeared that my only option to return a SOAP error was to manually output the required XML, which seemed like a 'really, do I have to' moment.

I was looking at the JADE WP WebServices_Security whitepaper, and although I am not intending to go full whole hogg in to WS-Security (Well, not initially at least), and they are doing a similar thing, and they are calling a raiseSecurityTokenException() method when things are missing from the header. Now it mentions this method in the document as far as to say
Lines 15 through 25 validate that the required headers are present. If they are not, an exception is raised by calling the raiseSecurityTokenException method, which is defined elsewhere in this document.
- although a search of the document finds no such definition elsewhere in the document?!. Although it is leading me to believe that the way to handle this is to raise an exception, but I feel that it will end up with manually writing XML out as the return error messages,

I was wondering if anyone could assist, or point me in a better direction if I am tackling this the wrong way. Ultimately the requirement is to check some supplied parameters in the SOAP request (One being the IP address so not really supplied in the SOAP, the rest are in the SOAP header), if the supplied parameters are not valid, or missing, or not correct in the context that they are tring to be used, then the request should be rejected, with a reasonably helpful SOAP error of course, and not continue.
Last edited by justin on Wed Apr 23, 2014 9:05 pm, edited 1 time in total.
“ If debugging is the process of removing software bugs, then programming must be the process of putting them in. ” - Edsger Dijkstra

Justin

murray
Posts: 144
Joined: Fri Aug 14, 2009 6:58 pm
Location: New Plymouth, New Zealand

Re: Web Serivce return error if invalid request

Postby murray » Tue Apr 22, 2014 7:20 pm

One option is to throw an exception. The Web Service specific exceptions are in the 11001-11091 range. You would likely already have an exception handler for any of these generated by Jade anyway. You can add details to the errorItem and extendedError text to suit. Otherwise, if it is warranted, you could set up your own class of exceptions.
Murray (N.Z.)

User avatar
justin
Posts: 7
Joined: Tue Apr 22, 2014 1:22 pm
Location: Nelson, New Zealand

Re: Web Service return error if invalid request

Postby justin » Wed Apr 23, 2014 9:18 am

Murray,

yeah I was starting to head in that direction anyway. I have given it a try and seems to be working fine, I was concerning I would have to serialize XML/SOAP error messages out myself but as you say raising the exception and letting Jade handle it with (what I am assuming) are the default SOAP exception handlers still wraps the error message up in SOAP nicely for me.

So in the end I wrote a method called raiseException (as below)

Code: Select all

raiseException(errorCode : Integer; errorItem,extendedText : String); vars except : NormalException; begin create except transient; except.errorCode := errorCode; except.errorItem := errorItem; except.extendedErrorText := extendedText; raise except; end;
and then from the parent class of all my web services I still override the processRequest method, and in essence just changed out the setError for my raiseException

Code: Select all

processRequest() updating, protected; vars ip_address : String; consumerValid : Boolean; begin ip_address := getServerVariable('REMOTE_ADDR'); consumerValid := getConsumer(ip_address); if not consumerValid then raiseException(23,"Unknown consumer","Unknown consumer"); endif; inheritMethod(); end;
and the SOAP it returns is the following

Code: Select all

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <soap:Fault> <faultcode>soap:Sender</faultcode> <faultstring>Error 23 - Unknown consumer</faultstring> <detail> <tns:faultDetails xmlns:tns="urn:JadeWebServices/WebServiceApp/"> <errorCode>23</errorCode> <errorItem>Unknown consumer</errorItem> <errorText>Unknown consumer</errorText> </tns:faultDetails> </detail> </soap:Fault> </soap:Body> </soap:Envelope>
although I know what you are saying about the SOAP exception codes ( 11001-11091), but it doesn't seem to make use of the standard exception constants, it just returns it. I am thinking that this allows me to publish a list of error codes to my consumers for their reference, pertinent to my application domain (what ever range I want, with whatever definitions I want). To be honest I would rather leave the JadeErrorCodesWebService codes out of it, to let them called by the system as appropriate, also I don't think it is appropriate to raise a JADEWS_DECIMAL_OVERFLOW (11055) myself, and the only one that seems pertinent is JADEWS_INVALID_REQUEST (11056) which seems a bit broad. I did actually try giving the errorCode of 11056 to the exception object, and it just returned it, with the errorItem and extendedErrorText I gave it, with not mention of JADEWS_INVALID_REQUEST. Also not clear as to what type of exception would be best, in the example I have used NormalException, I also tried JadeSOAPException and the response was no different.

Thanks for letting me bounce some ideas off you, did you think this is the best way to go?
Last edited by justin on Wed Apr 23, 2014 9:06 pm, edited 1 time in total.
“ If debugging is the process of removing software bugs, then programming must be the process of putting them in. ” - Edsger Dijkstra

Justin

murray
Posts: 144
Joined: Fri Aug 14, 2009 6:58 pm
Location: New Plymouth, New Zealand

Re: Web Serivce return error if invalid request

Postby murray » Wed Apr 23, 2014 2:34 pm

Regarding selection of Exception type, it will depend on how you want them caught (or not caught, as the case may be). NormalException is the superclass of JadeSOAPException, so "on NormalException" will catch both types, whereas "on JadeSOAPException" will only catch exceptions of that type. It depends whether the exception handler is specialised or more general in its scope. This is important when considering how multiple exception handlers are stacked up.

I have used 11052 "The service returned a fault message", in a Web Service consumer for some general errors that did not need to be more specific.
Murray (N.Z.)

User avatar
justin
Posts: 7
Joined: Tue Apr 22, 2014 1:22 pm
Location: Nelson, New Zealand

Re: Web Service return error if invalid request

Postby justin » Wed Apr 23, 2014 3:03 pm

Concerning the types of exception, what I was meaning was, because I am not arming any handlers directly myself, I am letting Jade handle the exceptions. In my head as far as webservices go there is really only two reponseses, a valid one (a SOAP:BODY with actual data or real results of the request) or a soap:Fault (Fault could be client or server), so I am assuming (I say assuming because I don't know this for a fact, but seems logical) that the Jade managed Webservice pipeline, ultimately always returns any problem/issue/exception as a soap:Fault.

With this idea in my head, any unhandled exception that gets passed to the Jade pipeline will ultimately return a soap:Fault - which is what appears to be happening, hence why I don't think it is of much consequence as to what exception (JadeSOAPException or NormalException) that is raised. Primarily because I am not arming granular tiers of exception handlers myself, I want the final result of any exception to be a soap:Fault.

Should the case arise that I have additional courses of action that are required based on different tiers of exceptions, then I agree that it would be pertinent to be clear as to what exception I am throwing and for what reason and then consequentially the handling of. Although I would probably do my own exception classes for this, primarily to keep my custom user exceptions separate from the generic or system ones.


In regard to the Error codes, what I was angling at, is how do you actually use the numbers? As I mentioned in my early post, it doesn't seem to matter what number I give it, it is just returns it in the XML. So unless the consumer knows what that number is (and BTW consumers will not be Jade consumers, think Java, or .NET), it won't mean anything unless I give them reference material (that is assuming there is no accompany friendly message that is sufficient to assist them). I suppose what I was expecting, was if I raised a 11056 errorCode (JADEWS_INVALID_REQUEST) or 11052 for that matter, I expected Jade to return a friendly string message that was relevant to that errorCode, without me having to explicitly set the message. I would of thought that would be the whole point of having the error codes - wouldn't it?
Last edited by justin on Wed Apr 23, 2014 9:06 pm, edited 1 time in total.
“ If debugging is the process of removing software bugs, then programming must be the process of putting them in. ” - Edsger Dijkstra

Justin

murray
Posts: 144
Joined: Fri Aug 14, 2009 6:58 pm
Location: New Plymouth, New Zealand

Re: Web Serivce return error if invalid request

Postby murray » Wed Apr 23, 2014 5:10 pm

I see your point regarding the Jade error codes. I have more experience building WS consumers, where the Jade error codes are meaningful. If you are relying on Jade's own exception handling then you probably have to accept its default behaviour. I know the frustration of getting a "catch-all" error from a WS provider where I had an ASP .Net Web Service that only ever seemed to return error "1007" for almost any sort of data error.
Murray (N.Z.)


Return to “Tips and Techniques”

Who is online

Users browsing this forum: Google [Bot] and 12 guests