<commit_before>/******************************************************************************/
/* ServerMethodInvocation                                                     */
/******************************************************************************/

Meteor._ServerMethodInvocation = function (name, handler) {
  var self = this;

  self._enclosing = null;
  self.isSimulation = null;
  self._name = name;
  self._handler = handler;
  self._async = false;
  self._responded = false;
  self._autoresponded = false;
  self._threw = false;
  self._callback = null;
  self._next = null;
  self._calledNext = false;
};

_.extend(Meteor._ServerMethodInvocation.prototype, {
  beginAsync: function (okToContinue) {
    var self = this;

    if (okToContinue === undefined)
      okToContinue = true;

    if (self.isSimulation)
      // XXX need a much better error message!
      // duplicated in livedata_connection
      throw new Error("Simulated methods may not be asynchronous");
    else if (self._responded)
      throw new Error("The method has already returned, so it is too late " +
                      "to mark it as asynchronous");
    else {
      self._async = true;
      if (okToContinue && !self._calledNext) {
        self._calledNext = true;
        self._next && self._next();
      }
    }
  },

  respond: function (ret) {
    this._sendResponse(undefined, ret, "async");
  },

  error: function (code, message) {
    this._sendResponse({error: code, reason: message}, undefined, "async");
  },

  // from: "async", "sync", or "throw".
  // self._threw is set by _run, and indicates that we're about to
  // report an exception and not to allow any other fibers kicked off by
  // the method to emit data.

  _sendResponse: function (error, ret, from) {
    var self = this;

    if (from === "throw")
      self._threw = true;

    if (self._threw && from !== "throw")
      // this is a different fiber.  don't emit data, don't print an error.
      return;

    if (self._responded) {
      // another fiber already reported a result to the client.  if
      // this fiber is throwing an exception, there's nothing left to do,
      // since methods can only return a single result.  the exception
      // has already been logged.  otherwise, throw an error: the user's
      // code is responding more than once.
      if (from === "throw")
        return;
      if (self._autoresponded)
        throw new Error(
          "The method has already returned, so it is too late to call " +
            "respond() or error(). If you want to respond asynchronously, " +
            "first use beginAsync() to prevent a response from being " +
            "automatically sent.");
      else
        throw new Error(
          "respond() or error() may only be called once per request");
    }
    self._responded = true;
    self._autoresponded = (from === "sync");

    // if we haven't yet yielded to the next method in the queue, do
    // that now, just before sending the response.
    if (!self._calledNext) {
      self._calledNext = true;
      self._next && self._next();
    }

    // call the callback.  should happen exactly once per method.
    self._callback && self._callback(error, ret);
  },
<commit_msg>support error() on sync methods on server (temporary)<commit_after>/******************************************************************************/
/* ServerMethodInvocation                                                     */
/******************************************************************************/

Meteor._ServerMethodInvocation = function (name, handler) {
  var self = this;

  self._enclosing = null;
  self.isSimulation = null;
  self._name = name;
  self._handler = handler;
  self._async = false;
  self._responded = false;
  self._response_was_error = null;
  self._autoresponded = false;
  self._threw = false;
  self._callback = null;
  self._next = null;
  self._calledNext = false;
};

_.extend(Meteor._ServerMethodInvocation.prototype, {
  beginAsync: function (okToContinue) {
    var self = this;

    if (okToContinue === undefined)
      okToContinue = true;

    if (self.isSimulation)
      // XXX need a much better error message!
      // duplicated in livedata_connection
      throw new Error("Simulated methods may not be asynchronous");
    else if (self._responded)
      throw new Error("The method has already returned, so it is too late " +
                      "to mark it as asynchronous");
    else {
      self._async = true;
      if (okToContinue && !self._calledNext) {
        self._calledNext = true;
        self._next && self._next();
      }
    }
  },

  respond: function (ret) {
    this._sendResponse(undefined, ret, "async");
  },

  error: function (code, message) {
    this._sendResponse({error: code, reason: message}, undefined, "async");
  },

  // from: "async", "sync", or "throw".
  // self._threw is set by _run, and indicates that we're about to
  // report an exception and not to allow any other fibers kicked off by
  // the method to emit data.

  _sendResponse: function (error, ret, from) {
    var self = this;

    if (from === "throw")
      self._threw = true;

    if (self._threw && from !== "throw")
      // this is a different fiber.  don't emit data, don't print an error.
      return;

    if (self._responded) {
      // another fiber already reported a result to the client.  if
      // this fiber is throwing an exception, there's nothing left to do,
      // since methods can only return a single result.  the exception
      // has already been logged.  otherwise, throw an error: the user's
      // code is responding more than once.
      if (from === "throw")
        return;
      if (from === "sync" && self._response_was_error)
        // it has to be OK to call this.error from a sync method,
        // because how else would you signal an error?
        return;
      if (self._autoresponded)
        throw new Error(
          "The method has already returned, so it is too late to call " +
            "respond() or error(). If you want to respond asynchronously, " +
            "first use beginAsync() to prevent a response from being " +
            "automatically sent.");
      else
        throw new Error(
          "respond() or error() may only be called once per request");
    }
    self._responded = true;
    self._response_was_error = !!error;
    self._autoresponded = (from === "sync");

    // if we haven't yet yielded to the next method in the queue, do
    // that now, just before sending the response.
    if (!self._calledNext) {
      self._calledNext = true;
      self._next && self._next();
    }

    // call the callback.  should happen exactly once per method.
    self._callback && self._callback(error, ret);
  },

{'fraction_non_alphanumeric': 0.1488454184438888, 'fraction_numerical': 0.0, 'mean_word_length': 2.492552645095018, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5433189', 'n_tokens_mistral': 1881, 'n_tokens_neox': 1793, 'n_words': 676}