Unable to make async rest request from a before business rule?

dachtman
Kilo Contributor

I have a business rule that runs on insert and update on a app scoped table.The business rule calls a restful webservice and based on the response the operation should either be aborted or continue.


When I run this as a before rule I get an error stating Use an async business rule to perform outbound HTTP requests. I have tried switching the webservice to use executeasync and that has caused more errors with truncation of the endpoint. I have also tried switching the business rule to async but that doesn't allow for me to stop the current operation.

22 REPLIES 22

Pradeep Sharma
ServiceNow Employee
ServiceNow Employee

Hi Darrin,



Please refer section 3.1 for more info on BR.


Business Rules - ServiceNow Wiki


All the scripts and tables are in the same scope. So according to section 3.1 I should be able to abort the action using a before business rule.


aklimenko
Mega Expert

I had the same problem but it was resolved by executeAsync and later waiting for it. Something like this:


var response = (new MyRestUtil()).execute(serviceNowEndPoint, typeMethod, parameters, domain);


response.waitForResponse(60);



MyRestUtil has something like:


var restCall = new sn_ws.RESTMessageV2(serviceNowEndPoint, typeMethod);


return restCall.executeAsync();



Hope this helps


Ok, so I'm having trouble with this. When using the "executeAsync" with "waitForResponse" the UI freezes until the request finishes. But if I use just execute, it completes and comes back quickly.



Take this business rule (I've put all the code here, but it shouldn't matter if it was in a script include or not):


Name: REST Call Testing


Table: Incident


Active: checked


Advanced: checked


When: before


Script:


function onBefore(current, previous) {


    //This function will be automatically called when this rule is processed.


   


var doAsync = false;


var bin = 'http://requestb.in/1jgih3k1'



try{


      var restMessage = new sn_ws.RESTMessageV2();


      restMessage.setBasicAuth("admin", "admin" );


      restMessage.setHttpMethod( "post" );


      restMessage.setEndpoint( bin );


      restMessage.setRequestBody("{\"short_description\" : \"Test incident\"}");


     


      if( !doAsync )


          var response = restMessage.execute();


      else {


          response = restMessage.executeAsync(); //Might throw exception if http connection timed out or some issue with sending request itself because of encryption/decryption of password.


          response.waitForResponse(60);// In seconds. Wait at most 60 seconds to get response from ECC Queue/Mid Server //Might throw exception timing out waiting for response in ECC queue.


      }


     


  responseBody = response.haveError() ? response.getErrorMessage() : response.getBody();


  status = response.getStatusCode();


} catch(ex) {


  responseBody = '' + ex; //ex.getMessage();


  status = '500';


} finally {


  requestBody = restMessage? restMessage.getRequestBody():null;


}


gs.info("Request Body: " + requestBody);


gs.info("Response: " + responseBody);


gs.info("HTTP Status: " + status);



  gs.addInfoMessage( 'Finished' );


}




If I have "doSync=true", then I get the big nasty message posted above: Illegal access to outbound HTTP in Testing6. Use an async business rule to perform outbound HTTP requests. But the request completes anyway!


However, if I have doSync=false, then the UI freezes until the request completes.




Did either of you experience this, or am I doing something wrong?