Скрипт Google Apps: передача ошибки в шаблонный HTML - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть следующий код:

code.gs:

function onOpen() {
    var ui = SpreadsheetApp.getUi();
    ui.createMenu('My Menu')
      .addItem('Test', 'showTestForm')
      .addToUi();
}

function showTestForm() {
    var html = HtmlService.createHtmlOutputFromFile('TestForm');
    SpreadsheetApp.getUi().showModalDialog(html, 'TEST');
}

function Test(formObject){
  Logger.log("TEST")
  var a = new Error( "Allready present "+ formObject);
  a.error_code = 99;
  Logger.log(JSON.stringify(a));
  throw a;
}

TestForm.html

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8" />
    <base target="_top">
    <script>
        function onFailure(error) {   
            var keys = Object.keys(error);
            alert(JSON.stringify(keys));
            alert(JSON.stringify(error.message));
            alert(JSON.stringify(error.error_code));
        }

        function onSuccess() {
            alert("Success");
        }
    </script>
</head>
<body>
    <input type="submit" value="Save" onclick="google.script.run.withFailureHandler(onFailure).withSuccessHandler(onSuccess).Test('1')" />
    <input type="button" value="Close" onclick="google.script.host.close()" />
</body>
</html>

Когда я открываю TestForm из меню и нажимаю «Сохранить»"У меня есть следующий журнал от Logger:

[18-12-24 23:08:24:765 PST] TEST
[18-12-24 23:08:24:766 PST] {"message":"Allready present 1","error_code":99}

Итак, я вижу, что объект ошибки имеет свойства 'message' и 'error_code'.Но в браузере у меня есть следующие предупреждения:

["name"]
"Error: Allready present 1"
undefined

Итак, я вижу, что у объекта с полученной ошибкой есть только одно пустое (я проверил) свойство "имя".Но если я обращаюсь к свойству «message», я получаю строку, как в исходном объекте (но не то же самое). И похоже, что у этого объекта нет poperty «error_code». В чем дело?

Ответы [ 2 ]

0 голосов
/ 15 января 2019

В соответствии с предложением @ TheMaster необходимо сделать следующее:

code.gs

function Test(formObject){
    var a = new Error( JSON.stringify({msg:"Allready present "+ formObject,code:99}));
    throw a;
}

TestForm.html

// removing "Error: " from message string to get our json back
var json = error.message.replace("Error: ",'')
var msg = JSON.parse(json).msg;
var code = JSON.parse(json).code;

То есть мы помещаем json в атрибут message объекта Error, а затем, вырезая наш json, анализируем его и получаем необходимые значения.

Это не совсем точноответ на вопрос, но хороший способ решить проблему.

0 голосов
/ 26 декабря 2018

Я подумал, что вам может понравиться полный рабочий пример, так как я знаю, что этот материал может быть довольно разочаровывающим.

Это простой шаблонный HTML-файл, который можно использовать как диалог илиWebApp.Все, что он делает, это создает файл Google Doc с текущей датой в верхнем и нижнем колонтитулах каждой страницы, и он помещает файл в тот же каталог, что и электронная таблица, содержащая скрипт.Вот и все.Я использую Chrome Browser.Мне даже все равно, не будут ли мои сценарии работать в другом браузере.

Вот HTML: (FileName: 'docwithdate.html')

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= include('resources') ?>
    <?!= include('css') ?>
  </head>
  <body>
    <?!= include('form') ?>
    <?!= include('script') ?>
  </body>
</html>

Ресурсы: (FileName: 'resources.html')

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

CSS: (FileName: 'css.html')

<style>
body {background-color:#ffffff;}
input[type="button"]{padding:0 0 2px 0;}
</style>

Форма: (FileName: form.html) Это, вероятно,продвинуть идею шаблонов немного дальше.

<form id="myForm" onsubmit="event.preventDefault();processForm(this);" >
  <input type="text" id="txt1" name="filename" />
  <input id="btn" type="submit" value="Submit" />
</form>

Javascript: [FileName: 'script.html')

<script>
    function createFile(){
      var name=document.getElementById('filename').value;
      google.script.run
      .withSuccessHandler(function(rObj){
        var html='<br /><a href="'+ rObj.url +'" onClick="google.script.host.close();">Go To File:' + rObj.filename + '</a>';
        $(html).appendTo("body");
      })
      .createTemplatedGoogleDoc(name);
    }

    function getInputObject(obj) {//I'm probably doing something wrong here. But this is what I had to do to get the object with the properties that I desired.  So if you have another way.  Go for it.
      var rObj={};
      for(var i=0;i<Object.keys(obj).length;i++){
        if(obj[i].type=="text"){
          rObj[obj[i].name]=obj[i].value;
        }
        console.log('Object.keys(rObj): %s',Object.keys(rObj).join(', '));
      }
      return rObj;
    }

    function processForm(obj){
      var fObj=getInputObject(obj);
      var name=fObj.filename;
      google.script.run
      .withSuccessHandler(function(rObj){
        document.getElementById("btn").disabled=true;
        var html='<br /><a href="'+ rObj.url +'" onClick="google.script.host.close();">Go To File:' + rObj.filename + '</a>';
        $(html).appendTo("body");
      })
      .createTemplatedGoogleDoc(name);
    }
    console.log('My Code');
</script>

Google Script: (FileName: Code.gs)

function onOpen(){
  SpreadsheetApp.getUi().createMenu('My Menu')
  .addItem("Open Templated Google Doc", 'showMyDialog')
  .addToUi()
}

function createTemplatedGoogleDoc(name){
  Logger.log(name);
  var doc=DocumentApp.create(name);//Creates a google doc
  var fldrs=DriveApp.getFileById(SpreadsheetApp.getActive().getId()).getParents();
  while(fldrs.hasNext()){
    var fldr=fldrs.next();
    if(fldr.getName()=="Create Templated Google Doc App"){
      var folder=fldr;
    }
  }
  Drive.Files.update({"parents": [{"id": folder.getId()}]}, doc.getId());//puts doc file into same directory as the spreadsheet that contains the script
  doc.addHeader().appendParagraph(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "E MMM dd, yyyy"));
  doc.addFooter().appendParagraph(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "E MMM dd, yyyy"));
  //doc.getBody().getChild(0).removeFromParent();
  doc.saveAndClose()
  var rObj={url:doc.getUrl(),filename:doc.getName()}
  return rObj;
}

function showMyDialog(){
  var ui=HtmlService.createTemplateFromFile('docwithdate').evaluate();
  SpreadsheetApp.getUi().showModelessDialog(ui, 'My Doc with Date');
}

function doGet(){//if you want a web app this is helpful
  return HtmlService.createTemplateFromFile('docwithdate').evaluate();
}

function include(filename){//this is the include that the template uses
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

Это довольно простой сценарий.Надеюсь, это поможет вам начать.

...