Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unhandled exceptions in Google Apps Script

I have created a public Web App with access to my private spreadsheet data. I can catch and log exceptions intry..catch, but:

  1. is it possible to catch all unhandled exceptions, like browsers window.onerror?
  2. can I view logs of unhandled exceptions somewhere?
  3. by exceptions like "Service invoked too many times" my app is even not getting run, so here I definitely can`t handle the exceptions. Is there logs with such kind of exceptions?

These are so simple questions, so that I'm bit confused to ask them, but after hours of research I could not find the answers.

Thank you in advance.

like image 726
tenbits Avatar asked Jul 04 '17 20:07

tenbits


People also ask

Why is my Google script not working?

There are a few possible causes for these errors: A Google server or system is temporarily unavailable. Wait for a few moments and try running the script again. There is an error in your script that doesn't have a corresponding error message.

How do I view logs in App script?

A basic approach to logging in Apps Script is to use the built-in execution log. To view these logs, at the top of the editor, click Execution log. When you run a function or use the debugger, the logs stream in real time. You can use either the Logger or console logging services in the built-in execution log.


1 Answers

These are issues that are being addressed currently. Right now in the Apps Script Early Access Program are two new additions that handle these cases. The first is native integration with stackdriver logging and the addition of google.script.run.withLogger().

First off for now you need to apply for the EAP:

https://developers.google.com/apps-script/guides/apps-script-eap

Stackdriver Logging:

To log to stackdriver the console object has been added to the server side.

code.gs

console.log('This will log to stackdriver')  

Check out the docs for all the methods of console.

https://developers.google.com/apps-script/guides/logging#stackdriver_logging

Example from the docs:

function measuringExecutionTime() {
  // A simple INFO log message, using sprintf() formatting.
  console.info('Timing the %s function (%d arguments)', 'myFunction', 1);

  // Log a JSON object at a DEBUG level. The log is labeled
  // with the message string in the log viewer, and the JSON content
  // is displayed in the expanded log structure under "structPayload".
  var parameters = {
      isValid: true,
      content: 'some string',
      timestamp: new Date()
  };
  console.log({message: 'Function Input', initialData: parameters});

  var label = 'myFunction() time';  // Labels the timing log entry.
  console.time(label);              // Starts the timer.
  try {
    myFunction(parameters);         // Function to time.
  } catch (e) {
    // Logs an ERROR message.
    console.error('myFunction() yielded an error: ' + e);
  }
  console.timeEnd(label);     
  }

In addition you can also check Log Exceptions in the scripts properties. This will generate a stackdriver entry every time any error occurs in your script.

Error recovery in a web app

To recover in a web app from a failure you have access to the withFailureHandler() method found in the google.script.run object. With this you can register a callback in the event your script hits an exception.

Full documentation can be found at:

https://developers.google.com/apps-script/guides/html/reference/run

If you are doing server side checks with try...catch you may be getting an exception but gracefully handling it. In this case withFailureHandler() will not execute and onSuccessHandler() propably isnt the best place to handle errors. In the EAP there is now a withLogger method to google.script.run. For now there no documentation for google.script.run.withLogger(). I found it by digging through devtools. withLogger() allows you to register a function as a callback when ever a stackdriver entry is created. This is particularly helpful when you have log exceptions checked in your script properties. In this sense it is a bit like withFailureHandler() but it can be triggered by any stackdriver entry you add though the server-side console object.

index.html

<script>
  google.script.run
        .withSuccessHandler(function(){console.log('OK')})
        .withFailureHandler(function(e){console.error(e)})
        .withLogger(function(e){console.warn("The following log was generated:"+e)})
        .serverFunctionCall();
</script>

code.gs

function serverFunctionCall(){
   console.log("This log will generate a callback");
   return true;

}
like image 82
Spencer Easton Avatar answered Sep 20 '22 16:09

Spencer Easton