How To Send An Error Status Code Like Bad Request (400) From A Google Script?
Solution 1:
Issue and workaround:
Unfortunately, in the current stage, ContentService
cannot modify the status code. When I saw the official document of Class ContentService, such method cannot be found. Ref It seems that this is the current specification.
So in your situation, as the current workaround, how about returning the value as JSON data? By this, you can check the value using the key of JSON data. For example, how about the following sample script?
When the correct value without the error is returned,
returnContentService.createTextOutput(JSON.stringify({value: 'value'}));
When the value with the error is returned,
return ContentService.createTextOutput(JSON.stringify({error: 'Error message'}));
When you need
.setMimeType(ContentService.MimeType.JSON)
, please add this.
Note:
- When I searched about this at the Google issue tracker, I couldn't find it. So how about reporting this as the future request? Ref
Reference:
Solution 2:
Here's another workaround that allows raising errors on the client side for errors on the web app side. For example, a client might need to catch errors such as bad url args sent to the web app (i.e. the OP's question), or catch errors thrown by a method that is called from doGet()
or doPost()
.
As far as I know, when an error is thrown downstream of doGet()
or doPost()
, a text error message is returned in the response, but the web app request itself succeeds, so there is no error thrown on the client side. As @Tanaike said, there still seems no way for a Google web app dev to throw an HTTP error from the app (like 400 Bad Request
or 500 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).
So the web app can be written to:
- return a function body that will throw an error for bad args, server method errors, etc.
- return a function body that will return intended JSON when there is no error
This is a bit of a hack, but it unifies error handling on the client side. 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. Then both Google-raised http errors and web app downstream errors can be caught in the catch{}
block.
Example setup for a Google Apps Script client making a request to a Google web app:
(1) In the web app doGet()
or doPost()
function:
// this string will be returned by the webappvar 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 methodelse {
try {
// if the method call succeeds, return a fnBody that will return the intended JSONvar 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 clientreturnContentService.createTextOutput(fnBody).setMimeType(ContentService.MimeType.TEXT);
(2) On the client side (Google apps script client making a POST request)
// Set the url, payload, and fetch optionsvar url = "https://script.google.com/_______/exec?arg1=val1&arg2=val2";
var payload = getPayloadString(); // whatever POST payload needs to be sentvar 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 apptry {
// make the POST request - this throws Google-generated HTTP errors if anyvar response = UrlFetchApp.fetch(url, options);
// create the dynamic function from the fnBody returnedvar responseFn = newFunction(response.getContentText());
// run the function - this returns intended JSON content// or throws web app downstream errors if anyvar responseJson = responseFn();
}
catch(err) {
// handle either source of error
console.log(err.message);
}
There are potential security risks associated with dynamic code, so I'm not sure how widely applicable this might be. I might use this in an aplication that lives entirely in a private GCP domain, i.e. with the web app restricted to same-domain users and the client app also in the same domain. Some security is also added by the 'use strict'
directive, which boxes the dynamic function in by setting its this
to undefined
(ref). But it's still a good idea to think through the dynamic code implications (ref1, ref2).
Post a Comment for "How To Send An Error Status Code Like Bad Request (400) From A Google Script?"