Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 引发自定义超时异常_Javascript_Google Apps Script_Try Catch_Timeoutexception - Fatal编程技术网

Javascript 引发自定义超时异常

Javascript 引发自定义超时异常,javascript,google-apps-script,try-catch,timeoutexception,Javascript,Google Apps Script,Try Catch,Timeoutexception,我有一个Google Apps脚本web app(“web app”),它以用户身份执行,然后通过Apps脚本API使用UrlFetchApp.fetch()从另一个Apps脚本项目(“API可执行文件”)调用各个函数,并以我的身份执行(请参阅) 此方法的一个限制是UrlFetchApp.fetch()有60秒的超时时间,我的一个函数通常需要更长的时间。API可执行函数成功完成运行,但web应用程序引发超时异常。我希望通过运行第二个“后续”函数来处理此异常,该函数查找并返回由原始函数成功创建的G

我有一个Google Apps脚本web app(“web app”),它以用户身份执行,然后通过Apps脚本API使用
UrlFetchApp.fetch()
从另一个Apps脚本项目(“API可执行文件”)调用各个函数,并以我的身份执行(请参阅)

此方法的一个限制是
UrlFetchApp.fetch()
有60秒的超时时间,我的一个函数通常需要更长的时间。API可执行函数成功完成运行,但web应用程序引发超时异常。我希望通过运行第二个“后续”函数来处理此异常,该函数查找并返回由原始函数成功创建的Google工作表的URL。但是,我需要将传递给原始函数的参数之一传递给后续函数,而在标准的try…catch块中似乎无法做到这一点

我的想法是抛出一个包含所需参数的异常,但我不知道如何抛出自己的超时异常;由于Google Apps脚本是同步的,所以无法跟踪运行时运行了多长时间
UrlFetchApp.fetch()

有没有办法抛出自己的超时异常?或者,是否有其他方法可以将所需的参数传递给在出现超时错误时执行的函数

我在这篇文章中也标记了Javascript,因为它与Google Apps脚本有很多重叠,我认为这会提高我与有答案的人联系的机会——希望没问题。下面是我在我的web应用程序中用来调用API可执行函数的函数,以防有用

编辑:根据@TheMaster的评论,我决定编写脚本,就像传递给
executeAsMe()
的参数被传递给
catch()
块一样,以查看发生了什么。关于
opt_timeoutFunction
未定义这一事实,我预期会出现异常,但奇怪的是,它看起来只有
catch()
块的第一行正在运行,我不知道为什么

function executeAsMe(functionName, paramsArray, opt_timeoutFunction, opt_timeoutParams) {
  try {
    console.log('Using Apps Script API to call function ' + functionName.toString() + ' with parameter(s) ' + paramsArray.toString());

    var url = 'https://script.googleapis.com/v1/scripts/Mq71nLXJPX95eVDFPW2DJzcB61X_XfA8E:run';

    var payload = JSON.stringify({"function": functionName, "parameters": paramsArray, "devMode": true})

    var params = {method:"POST",
                  headers: {Authorization: 'Bearer ' + getAppsScriptService().getAccessToken()},
                  payload:payload,
                  contentType:"application/json",
                  muteHttpExceptions:true};

    var results = UrlFetchApp.fetch(url, params);
    var jsonResponse = JSON.parse(results).response;
    if (jsonResponse == undefined) {
      var jsonResults = undefined;
    } else {
      var jsonResults = jsonResponse.result;
    }
  } catch(error) {
    console.log('error = ' + error); // I'm seeing this in the logs...
    console.log('error.indexOf("Timeout") = ' + error.indexOf("Timeout").toString); // ...but not this. It skips straight to the finally block
    if (error.indexOf('Timeout') > 0) { // If error is a timeout error, call follow-up function
      console.log('Using Apps Script API to call follow-up function ' + opt_timeoutFunction.toString() + ' with parameter(s) ' + paramsArray.toString());

      var url = 'https://script.googleapis.com/v1/scripts/Mq71nLXJPX95eVDFPW2DJzcB61X_XfA8E:run';

      var payload = JSON.stringify({"function": opt_timeoutFunction, "parameters": opt_timeoutParams, "devMode": true})

      var params = {method:"POST",
                    headers: {Authorization: 'Bearer ' + getAppsScriptService().getAccessToken()},
                    payload:payload,
                    contentType:"application/json",
                    muteHttpExceptions:true};

      var results = UrlFetchApp.fetch(url, params);
      var jsonResponse = JSON.parse(results).response;
      if (jsonResponse == undefined) {
        var jsonResults = undefined;
      } else {
        var jsonResults = jsonResponse.result;
      }
    }
  } finally {
    console.log('jsonResults = ' + jsonResults);
    return jsonResults;
  }

}
我最终使用了'''catch()''块将异常抛出回客户端并在那里处理它

谷歌应用程序脚本:

function executeAsMe(functionName, paramsArray) {
  try {
    console.log('Using Apps Script API to call function ' + functionName.toString() + ' with parameter(s) ' + paramsArray.toString());

    var url = 'https://script.googleapis.com/v1/scripts/Mq71nLXJPX95eVDFPW2DJzcB61X_XfA8E:run';

    var payload = JSON.stringify({"function": functionName, "parameters": paramsArray, "devMode": true})

    var params = {method:"POST",
                  headers: {Authorization: 'Bearer ' + getAppsScriptService().getAccessToken()},
                  payload:payload,
                  contentType:"application/json",
                  muteHttpExceptions:true};

    var results = UrlFetchApp.fetch(url, params);
    var jsonResponse = JSON.parse(results).response;
    if (jsonResponse == undefined) {
      var jsonResults = undefined;
    } else {
      var jsonResults = jsonResponse.result;
    }
    return jsonResults;
  } catch(error) {
    console.log('error = ' + error);
    if (error.toString().indexOf('Timeout') > 0) {
      console.log('Throwing new error');
      throw new Error('timeout');
    } else {
      throw new Error('unknown');
    }
  } finally {
  }
}
客户端Javascript(简化版本):

函数createMcs(){
var userFolder=getDataFromHtml().userFolder;
google.script.run
.withSuccessHandler(CreateMcsAccess)
.withFailureHandler(createMcsFailure)
.withUserObject(用户文件夹)
.executeAsMe('createMasterCombinedSchedule',[userFolder]);
}
函数createMCSSAccess(mcsParameter){
如果(mcsParameter==未定义){
simpleErrorModal.style.display=“block”//一般错误消息
}否则{
document.getElementById(“SimpleAllertHeaderDiv”).innerHTML='Master Combined Schedule Created Successfully';
document.getElementById(“SimpleAllertBodyDiv”).innerHTML='您的主组合计划已成功创建。单击以查看';
simpleAlertModal.style.display=“块”;
}
}
函数createMcsFailure(mcsError,userFolder,counter){//我抛出的异常将激活此函数
如果(!counter){//在每次运行checkForCreatedMcs()时都添加一个计数器以递增,这样它就不会无限期运行
var计数器=0;
}
如果(mcsError.message=='Error:timeout'&&counter<5){//如果超时错误,请等待10秒并查找MCS URL
setTimeout(checkForCreatedMcs(mcsError,userFolder,counter),10000);
}否则,如果(mcsError.message=='Error:timeout'&&counter==5){//如果在5次尝试后仍不起作用,则显示一般错误消息
simpleErrorModal.style.display=“块”;
}else{//对于任何不是超时异常的错误,显示一般错误消息
simpleErrorModal.style.display=“块”;
}
}
函数checkForCreatedMcs(mcsError、userFolder、counter){
计数器++;
google.script.run
.withSuccessHandler(CheckForCreatedMCSuccess)
.withUserObject([mcsError,userFolder,counter])
.executeAsMe('checkifmcsexsists',[userFolder]);//checkifmcsexsists()是我在别处使用过的API可执行项目中预先存在的函数
}
函数checkForCreatedMcsSuccess(mcsExistsParameter,params){
var mcsError=params[0];
var userFolder=params[1];
var计数器=参数[2];
如果(mcsExistsParameter==undefined){//如果函数返回undefined,则显示一般错误消息
simpleErrorModal.style.display=“块”;
}否则,如果(mcsExistsParameter==false){//如果函数返回false,请等待10秒,然后重试
createMcsFailure(mcsError、userFolder、counter);
}else{//如果函数返回URL,则使用链接显示成功模式
document.getElementById(“SimpleAllertHeaderDiv”).innerHTML='Master Combined Schedule Created Successfully';
document.getElementById(“SimpleAllertBodyDiv”).innerHTML='您的主组合计划已成功创建。单击以查看';
simpleAlertModal.style.display=“块”;
}
}
我确信必须有一个更整洁/不那么复杂的方法来完成这项工作,但这是有效的

我最终使用了'''catch()''块将异常抛出回客户端并在那里处理它

谷歌应用程序脚本:

function executeAsMe(functionName, paramsArray) {
  try {
    console.log('Using Apps Script API to call function ' + functionName.toString() + ' with parameter(s) ' + paramsArray.toString());

    var url = 'https://script.googleapis.com/v1/scripts/Mq71nLXJPX95eVDFPW2DJzcB61X_XfA8E:run';

    var payload = JSON.stringify({"function": functionName, "parameters": paramsArray, "devMode": true})

    var params = {method:"POST",
                  headers: {Authorization: 'Bearer ' + getAppsScriptService().getAccessToken()},
                  payload:payload,
                  contentType:"application/json",
                  muteHttpExceptions:true};

    var results = UrlFetchApp.fetch(url, params);
    var jsonResponse = JSON.parse(results).response;
    if (jsonResponse == undefined) {
      var jsonResults = undefined;
    } else {
      var jsonResults = jsonResponse.result;
    }
    return jsonResults;
  } catch(error) {
    console.log('error = ' + error);
    if (error.toString().indexOf('Timeout') > 0) {
      console.log('Throwing new error');
      throw new Error('timeout');
    } else {
      throw new Error('unknown');
    }
  } finally {
  }
}
客户端Javascript(简化版本):

函数createMcs(){
var userFolder=getDataFromHtml().userFolder;
google.script.run
.withSuccessHandler(CreateMcsAccess)
.withFailureHandler(createMcsFailure)
.withUserObject(用户文件夹)
.executeAsMe('createMasterCombinedSchedule',[userFolder]);
}
函数createMCSSAccess(mcsParameter){
如果(mcsParameter==未定义){
simpleErrorModal.style.display=“block”//一般错误消息
}否则{
document.getElementById(“simpleAl