Google Apps脚本中的失败处理程序接收的对象与服务器端投放的对象不同

时间:2017-09-02 19:26:28

标签: google-apps-script

我的应用程序将提交的表单数据发送到此服务器端函数:

function processFormData(data)
{
  data = JSON.parse(data);
  // validate data
  var errorObject = {},
      potholeErrors = createErrorObjectFor('pothole'),
      intervalSizeErrors = createErrorObjectFor('intervalSize');
  // make sure numbers are actual numbers and not NaN's.
  if (!validateNumber(data.potholeWidth))
  {
    potholeErrors.messages.push(errorTypes.NOT_A_NUMBER);
    errorObject.potholeWidth = potholeErrors;
  }
  if (!validateNumber(data.intervalSize))
  {
    intervalSizeErrors.messages.push(errorTypes.NOT_A_NUMBER);
    errorObject.intervalSize = intervalSizeErrors;
  }  
  // make sure numbers are within their respective bounds (handled by handleErrors())
  errorObject = handleErrors(data, errorObject);
  // if intervalSize doesn't divide potholeWidth, make it so
  if (data.potholeWidth % data.intervalSize > 0) data.potholeWidth = nextMultiple(data.intervalSize, data.potholeWidth);
  // if there is anything in errorObject, throw it
  if (Object.getOwnPropertyNames(errorObject).length != 0)
  {
    Logger.log('errorObject == ' + JSON.stringify(errorObject, null, '\t'));
    throw errorObject;
  }
  // createSpreadsheet
  return createSpreadsheet(data.spreadsheet, data.potholeWidth, data.intervalSize);
}
成功之后,它完全符合它应该做的事情。但是,当最终用户输入任何无效输入时,服务器端抛出的对象与他们最终得到的对象不同。我尝试进入太小的坑洞宽度。当我在服务器端检查Logger时,我看到了正确的输出:

what the client side SHOULD be getting....

但是,在Developer控制台中,我看到了:

what the client side ACTUALLY gets....

将数据传送到服务器的代码如下所示:

function updateURL(url)
    {
        // activate button
        $('#input[type="submit"]').prop('disabled', ''); 
        // change href of #spreadsheetLink
        $('#spreadsheetLink').attr('href', url);
        // unhide the link's container if hidden
        if ($('#spreadsheetLink').parent().hasClass('hidden'))  $('#spreadsheetLink').parent().removeClass('hidden');
        // hide the 'Loading...' element
        if (!$('#loading').hasClass('hidden')) $('#loading').addClass('hidden');
    }

    function emailLink()
    {
        google.script.run.withSuccessHandler(function() { 
            $('#emailLink').next().text('E-mail message has been sent!');
            $('#emailLink').prop('disabled', 'disabled');
        }).emailLink($('#spreadsheetLink').attr('href'));
    }

    function handleFails(failData)
    {
        var DEBUG = true;
        if (DEBUG)  console.log('failData == ' + JSON.stringify(failData, null, '\t'));
        // hide 'Loading...' element
        if (!$('#loading').hasClass('hidden')) $('#loading').addClass('hidden');
        // for now, let's ignore any Errors/TypeErrors.
        if ((!failData instanceof Error) && (!failData instanceof TypeError))
        {
            // for now, if there were any errors with any of the fields, simply mark them as .invalid
            if ((failData.potholeWidth) && (failData.potholeWidth.messages.length > 0))
            {
                if (!$('#potholeWidth').hasClass('invalid')) $('#potholeWidth').addClass('invalid');
            }
            if ((failData.intervalSize) && (failData.intervalSize.messages.length > 0))
            {
                if (!$('#intervalSize').hasClass('invalid')) $('#intervalSize').addClass('invalid');
            }
        }
    }

    function submitFormData()
    {
        // hide spreadsheetLink container if not already done, and clear its <span> element if not already clear
        var spreadsheetLinkContainer = $('#spreadsheetLink').parent(),
            spanElement = $('spreadsheetLinkContainer').find('span');
        if (!$(spreadsheetLinkContainer).hasClass('hidden')) $(spreadsheetLinkContainer).addClass('hidden');
        if ($(spanElement).text() != '') $(spanElement).text('');
        // get all data
        var potholeWidth = parseNumberField('potholeWidth'),
            intervalSize = parseNumberField('intervalSize') || defaults.get('intervalSize'),
            concaveEdges = $('input[name="concaveEdges"]').filter(function() { return $(this).prop('checked'); }).next().text() === 'Yes',
            spreadsheetName = parseField('spreadsheetName') || defaults.get('spreadsheetName');
        // make button inactive
        if (($(this).prop('tagName')) && ($(this).prop('tagName').toLowerCase() == 'input'))    $(this).prop('disabled', 'disabled');
        // show "Loading..." element
        if ($('#loading').hasClass('hidden')) $('#loading').removeClass('hidden');
        // submit this data to the server
        google.script.run.withSuccessHandler(updateURL).withFailureHandler(handleFails).processFormData(JSON.stringify({
            potholeWidth: potholeWidth,
            intervalSize: intervalSize,
            concaveEdges: concaveEdges,
            spreadsheet : spreadsheetName
        }));
    }

,HTML看起来像这样:

<form>
        Place straightedge/yardstick along width of pothole such that it points at the corners, <a class="showImage">like this</a>
        <span class="row">
          <label class="firstColumn seventeenTwentieths">Pothole width (in inches): </label>
          <input type="text" class="secondColumn tenth numberField" id="potholeWidth" required />
        </span>
        <span class="rowTight">
          <label class="firstColumn seventeenTwentieths">Interval size (in inches, default 1 inch): </label>
          <input type="text" class="secondColumn tenth numberField" id="intervalSize" value="1" />
        </span>
        <div class="rowTight">
          <label class="firstColumn">Do any of the edges intersect the straightedge/yardstick other than at the corners?</label>
          <div class="secondColumn">
            <span>
              <input type="radio" name="concaveEdges" id="yesConcaveEdges" />
              <label for="yesConcaveEdges">Yes</label>
            </span>
            <br>
            <span>
              <input type="radio" name="concaveEdges" id="noConcaveEdges" checked />
              <label for="noConcaveEdges">No</label>
            </span>
          </div>
        </div>
        <span class="rowTight">
          <label class="firstColumn half">Spreadsheet name: </label>
          <input type="text" class="secondColumn nineTwentieths" id="spreadsheetName"/>
        </span>
        <span class="center row">
          <button class="center" id="clearForm">Clear</button>
          <input type="submit" class="center action" value="Create spreadsheet" />
        </span>
      </form>
      <span id="loading" class="row center fullWidth hidden">
      Loading...
      </span>
      <span class="row center fullWidth hidden">
        <a href="#" id="spreadsheetLink">Here is your spreadsheet</a>
        <button id="emailLink">E-mail me the link</button>
        <span></span>
      </span>

客户端实际获得的对象是什么以及如何确保它获取服务器实际抛出的对象?

1 个答案:

答案 0 :(得分:1)

我修好了。

我做了什么

在code.gs

而不仅仅是throw errorObject;,我说throw JSON.stringify(errorObject);

在JavaScript.html文件中

handleFails()中,我将服务器端的字符串转换回对象(failData = JSON.parse(failData))以使用它。它输出正确,一切都很好。

我学到了什么

服务器提供或接收数据的任何时间,必须以字符串的形式出现! (使用JSON.stringify()将该数据设为字符串!)