Servicenow脚本无限递归

时间:2017-06-07 07:08:44

标签: servicenow

我有以下ServiceNow脚本,它将记录插入live_message表。

(function executeRule(current, previous/*null when async*/) {


  var requestBody;
  var responseBody;
  var status;
  var request;
  var response;

  try {

    request = new sn_ws.RESTMessageV2("LiveMessageWebhook", "post");

    request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");


    var parameters = "&chat_message=" + current.chat_message.toString();
    parameters = parameters + "&context=" + current.context.toString();
    parameters = parameters + "&formatted_message=" + current.formatted_message.toString();
    parameters = parameters + "&has_attachments=" + current.has_attachments.toString();
    parameters = parameters + "&has_links=" + current.has_links.toString();
    parameters = parameters + "&has_tags=" + current.has_tags.toString();
    parameters = parameters + "&ID=" + current.id.toString();
    parameters = parameters + "&in_reply_to=" + current.in_reply_to.toString();
    parameters = parameters + "&isLiked=" + current.is_liked.toString();
    parameters = parameters + "&lastActivity=" + current.last_activity.toString();
    parameters = parameters + "&lastMessage=" + current.last_message.toString();
    parameters = parameters + "&likeCount=" + current.like_count.toString();
    parameters = parameters + "&message=" + current.message.toString();
    parameters = parameters + "&next_reply_order_chunk=" + current.next_reply_order_chunk.toString();
    parameters = parameters + "&order=" + current.order.toString();
    parameters = parameters + "&poll=" + current.poll.toString();
    parameters = parameters + "&private=" + current.private_message.toString();
    parameters = parameters + "&profile=" + current.profile.toString();
    parameters = parameters + "&reflected_field=" + current.reflected_field.toString();
    parameters = parameters + "&reply_to=" + current.reply_to.toString();
    parameters = parameters + "&state=" + current.state.toString();
    parameters = parameters + "&group_type=" + current.sys_class_name.toString();
    parameters = parameters + "&created_by=" + current.sys_created_by.toString();
    parameters = parameters + "&created_on=" + current.sys_created_on.toString();
    parameters = parameters + "&domain=" + current.sys_domain.toString();
    parameters = parameters + "&domain_path=" + current.sys_domain_path.toString();
    parameters = parameters + "&sys_ID=" + current.sys_id.toString();
    parameters = parameters + "&to_profile=" + current.sys_domain.toString();
    parameters = parameters + "&updates=" + current.sys_mod_count.toString();
    parameters = parameters + "&updated_by=" + current.sys_updated_by.toString();
    parameters = parameters + "&updated_on=" + current.sys_updated_on.toString();

    request.setRequestBody(encodeURI(parameters));
    var l = request.getRequestBody();
    response = request.execute();

    responseBody = response.haveError()
      ? response.getErrorMessage()
      : response.getBody();
    status = response.getStatusCode();
    {
      var gr = new GlideRecord('live_message');

      gr.initialize();
      gr.chat_message = current.chat_message;
      gr.context = current.context.toString();
      gr.formatted_message = "abc";
      gr.group = current.group;
      gr.has_attachments = current.has_attachments;
      gr.has_links = current.has_links;
      gr.has_tags = current.has_tags;
      gr.id = current.id;
      gr.in_reply_to = "admin";
      gr.is_liked = current.is_liked;
      gr.last_activity = current.last_activity;
      gr.last_message = current.last_message;
      gr.like_count = current.like_count;
      gr.message = "abc";
      gr.next_reply_order_chunk = current.next_reply_order_chunk;
      gr.order = current.order;
      gr.poll = current.poll;
      gr.private_message = current.private_message;
      gr.profile = current.profile;
      gr.reflected_field = current.reflected_field;
      gr.reply_to = current.reply_to;
      gr.state = current.state;

      gr.sys_class_name = current.sys_class_name;
      gr.sys_created_by = current.sys_created_by;
      gr.sys_created_on = current.sys_created_on;
      gr.sys_domain = current.sys_domain;
      gr.sys_domain_path = current.sys_domain_path;
      gr.sys_mod_count = current.sys_mod_count;
      gr.sys_updated_by = current.sys_updated_by;
      gr.sys_updated_on = current.sys_updated_on;
      gr.to_profile = current.to_profile;
      gr.insertWithReferences();

    }

  } catch (ex) {
    responseBody = 'Exception: ' + ex;
    status = '900';
    requestBody = request
      ? request.getRequestBody()
      : null;
  } finally {
    gs.info("Final: Request Body: " + requestBody);
    gs.info("Final: Response: " + responseBody);
    gs.info("Final: HTTP Status: " + status);
    gs.addInfoMessage('Final: Finished');
  }

})(current, previous);

但是在插入记录之后它再次返回到try块并再次完成整个事情,现在使用插入的记录

1 个答案:

答案 0 :(得分:2)

如何配置此业务规则? 是否可能 此脚本,还可以触发脚本运行?

以下是我的意思的一个例子: 想象一下,我有一个业务规则,无论何时表中的记录都会执行" u_arbitrary_counter"已更新。 想象一下,这个业务规则的功能是每当更新这样的记录时,我们都会增加" u_counter"一个字段,如下:

current.setValue('u_counter', parseInt(current.getValue('u_counter')) + 1);
current.update();

通过使用.update(),我强制更新数据库,即使这是"之前"商业规则。

  

专业提示:请注意"之前"业务规则运行在即将发布的数据上   保存到数据库,BEFORE实际数据库操作已采取   地点。对"当前"的任何更改"之前的对象"商业规则   即使没有使用current.update也会保存,因为你是   无论如何,修改即将发送到数据库的数据   这个行动的自然过程。

因此在BEFORE业务规则中使用current.update()并不是一个好主意。出于同样的原因,执行任何其他操作必然会导致数据库更新,这可能触发相同的业务规则是一个坏主意。它不一定是current.update() - 相反,想象一下,如果不是更新当前记录,我做了类似......

var gr = new GlideRecord('u_arbitrary_counter'); //the same table this BR is running on
gr.initialize();
gr.setValue('u_counter', parseInt(current.getValue('u_counter')) + 1);
gr.insert(); //This triggers a database action!

出于同样的原因,这并不好。 同样,任何REST调用都会触发此表上可能触发此业务规则的数据库操作。

解决方案

如果这确实是您的问题的原因(并且不知道您的业务规则的配置,我无法确定它是否存在),实际上有一种方法可以告诉系统不要运行脚本执行操作后的任何其他业务规则。在你的gr.insertWithReferences();行(第91行)之前,如果代码块是问题(我非常有信心),请添加:

gr.setWorkflow(false);

这可以防止业务规则运行。 不幸的是,由于您将记录放入live_message表中,可能也不是一个好主意,因为信使可能需要一些业务规则来传播或在插入后显示该信息;我不确定。 如果是这种情况,我建议您在业务规则中添加一个条件,使其仅在某些情况下运行,然后将插入的记录设置为满足这些条件。

  

专业提示: PS - 我注意到您在某些地方使用current.field_name.toString()访问表字段,并直接访问   其他人current.field_name。虽然前者是可以接受的(不是   我在大多数情况下推荐它,后者应该几乎不会   使用 - 除了日志字段的情况。相反,我强烈   建议使用适当的getter / setter方法,以避免   传递参考问题和混淆,并确保你没有   依赖于JavaScript的coersion,它并不总是很好用   Mozilla Rhino,ServiceNow在后端运行。 Example issue here。有关详细信息,请参阅my article on using getValue() and setValue() in ServiceNow