Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Method UrlFetchApp.fetch invoked in the global scope." of Google Apps Script Ediotor Execution Hints

I'm developing a google spreadsheet add-on in google apps script editor.

As https://developers.google.com/apps-script/add-ons/lifecycle said, sometimes script run with limit authorized mode, so we won't write any code required high priviliges(like UrlFetch) in the global scope.

Warning: When your onOpen(e) function runs, the entire script is loaded and any global statements are executed. These statements execute under the same authorization mode as onOpen(e) and will fail if the mode prohibits them. This prevents onOpen(e) from running. If your published add-on fails to add its menu items, look in the browser's JavaScript console to see if an error was thrown, then examine your script to see whether the onOpen(e) function or global variables call services that aren't allowed in AuthMode.NONE.

But I found a very strange behavior of "invoked in the global scope". I put all my code inside the closure, and call them, but still got warning said I'm run UrlFetchApp in the global scope.

at last, I found out the difference between "run in global scope" v.s. "not global", is because the first one is var g = function () { /* UrlFetchApp here */ } , and the second one is function ng() { /* UrlFetchApp here */ ].

The below code can be ran inside Google Script Editor. If you run testGlobalScope() with T.g(), will get the warning. How ever when run T.ng() only, it's ok.

var T = (function() {
  var g = function () {
    // Method UrlFetchApp.fetch invoked in the global scope.
    try { UrlFetchApp.fetch('http://google.com') } catch (e) {}
  }

  function ng() {
    try { UrlFetchApp.fetch('http://google.com') } catch (e) {}
  }

  return {
    g: g
    , ng: ng
  }

}())

function testGlobalScope() {
  T.g() // T.g() will cause Script Editor show "Execution Hints" with red light: Method UrlFetchApp.fetch invoked in the global scope.
//  T.ng() // This will not show any warning.
}

My question is:

  1. why they have this kind of difference?
  2. if I still want to use module pattern like var T = (function () {}()), how could I get rid of "run in global scope" problem?
like image 684
Huan Avatar asked Feb 18 '16 10:02

Huan


1 Answers

This one is rather old, but will try to answer.

0) Though the warning is really shown in the script editor, it didn't seem to prevent onOpen function from running even when no permissions were given to the script. So it could be that the warning is shown for no actual reason.

0.1) Still, it is shown and it doesn't matter how exactly you declare T: be it function T(), var T = function T() { ... } or var T = (function() { ... }()), the warning is going to be shown.

1) Don't really know, can only make assumptions based on the above and the below (maybe Execution hints will think that any anonymous function belongs to global scope?).

2) But looks like there's a way to get rid of the warning while still declaring function as an expression, though g will need to be a named function:

var T = (function() {
  var g = function g() {
    // No "Method UrlFetchApp.fetch invoked in the global scope." warning
    try { UrlFetchApp.fetch('http://google.com') } catch (e) {}
  }

  function ng() {
    try { UrlFetchApp.fetch('http://google.com') } catch (e) {}
  }

  return {
    g: g
    , ng: ng
  }

})()
like image 180
a-change Avatar answered Oct 19 '22 15:10

a-change