繁体   English   中英

如何从谷歌脚本发送错误状态代码,如错误请求(400)?

[英]How to send an error status code like Bad Request (400) from a google script?

这是 Google 应用程序中的一个doPost function,它返回一条Hello World消息。

function doPost(e){

  return ContentService.createTextOutput('Hello World');
} 

现在假设我只想接受要发布到此 Google App 端点的有效 JSON 并且我想发送一个带有错误请求状态的响应。 我怎样才能做到这一点。 这是伪代码:

function doPost(e){
  try{
     const data = JSON.parse(e.postData.contents);
     return ContentService.createTextOutput('Hello World');
  }catch(err){
      // Send Bad Request
  }      

} 

问题和解决方法:

不幸的是,在当前阶段, ContentService无法修改状态码。 当我看到Class ContentService的官方文档时,找不到这样的方法。 Ref似乎这是当前的规范。

因此,在您的情况下,作为当前的解决方法,如何将值返回为 JSON 数据? 这样,您可以使用 JSON 数据的键检查值。 例如,下面的示例脚本怎么样?

  • 当返回没有错误的正确值时,

     return ContentService.createTextOutput(JSON.stringify({value: 'value'}));
  • 当返回有错误的值时,

     return ContentService.createTextOutput(JSON.stringify({error: 'Error message'}));
  • 当您需要.setMimeType(ContentService.MimeType.JSON)时,请添加此内容。

笔记:

  • 当我在谷歌问题跟踪器上搜索这个时,我找不到它。 那么如何将其报告为未来的请求呢? 参考

参考:

这是另一个解决方法,它允许在客户端针对 web 应用程序端的错误引发错误。 例如,客户端可能需要捕获错误,例如发送到 web 应用程序的错误 url 参数(即 OP 的问题),或捕获从doGet()doPost()调用的方法引发的错误。

据我所知,当doGet()doPost()下游抛出错误时,响应中返回文本错误消息,但 web 应用程序请求本身成功,因此客户端没有抛出错误。 正如@Tanaike 所说,Google web 应用程序开发人员似乎仍然无法从应用程序中抛出 HTTP 错误(如400 Bad Request500 Internal Server Error )。

The idea involves returning a function body from the web app, which the client can use to create and run a dynamic function via the Function() constructor (this assumes Javascript is available on the client).

因此 web 应用程序可以写入:

  • 返回一个 function 主体,该主体将针对错误的参数、服务器方法错误等引发错误。
  • 返回一个 function 主体,当没有错误时将返回预期的 JSON

这有点小技巧,但它统一了客户端的错误处理。 The client makes the http request, constructs a function using the function body returned in the response, and then runs this function, all in one try{} block. 然后可以在catch{}块中捕获 Google 引发的 http 错误和 web 应用程序下游错误。

Google Apps 脚本客户端向 Google web 应用程序发出请求的示例设置:

(1) 在 web 应用程序doGet()doPost() function 中:

// this string will be returned by the webapp
var fnBody;

// for bad url args, return a fnBody that will throw an error with an indicative message 
if(!urlArgsOk()) {
  fnBody =  "'use strict'; throw new Error('POST args error');";  
} 
// if url args are ok, call server method
else {
    try {
      // if the method call succeeds, return a fnBody that will return the intended JSON
      var returnObj = myServerMethod(methodArgs);
      fnBody = "'use strict'; return JSON.stringify(" + JSON.stringify(returnObj) + ");";
    }
    catch(serverErr) {
      // if the method call fails, return a fnBody that will throw an error ...
      // ... simple example shown here, but info from serverErr can be included in fnBody
      fnBody =  "'use strict'; throw new Error('server error');";  
    } 
}    

// return fnBody, which can be run via Function() on the client
return ContentService.createTextOutput(fnBody).setMimeType(ContentService.MimeType.TEXT);

(2) 在客户端(Google Apps 脚本客户端发出 POST 请求)

// Set the url, payload, and fetch options
var url = "https://script.google.com/_______/exec?arg1=val1&arg2=val2";
var payload = getPayloadString(); // whatever POST payload needs to be sent

var options = {
  'method' : 'POST',
  'contentType': 'application/json',
  'muteHttpExceptions': false, // let Google http exceptions come through
  'payload' : payload,
  'headers': {authorization: "Bearer " + ScriptApp.getOAuthToken()}
};

// Send a request to the web app
try {

  // make the POST request - this throws Google-generated HTTP errors if any
  var response = UrlFetchApp.fetch(url, options);

  // create the dynamic function from the fnBody returned
  var responseFn = new Function(response.getContentText());
  
  // run the function - this returns intended JSON content
  // or throws web app downstream errors if any
  var responseJson = responseFn();

}
catch(err) {
   // handle either source of error
   console.log(err.message);
}

动态代码存在潜在的安全风险,所以我不确定它的适用范围有多广。 我可能会在完全位于私有 GCP 域中的应用程序中使用它,即 web 应用程序仅限于同域用户,客户端应用程序也在同一个域中。 'use strict'指令还增加了一些安全性, this指令将动态 function 设置为undefined (ref) 但是考虑动态代码的含义仍然是一个好主意(ref1 , ref2)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM