Google Apps Scripts + Honeybadger = ❤️

Jan Bajena
Nov 18, 2018 · 3 min read

Recently I’ve been working on Google Data Studio Connectors (you can read more about it here) which are advanced Google Apps Scripts. During the first few weeks after shipping the code to production, I had been constantly checking the executions list in order to quickly find and react to any incoming bugs. This process quickly became annoying, so I started browsing the web trying to find a way of automating it.

Unfortunately, I didn’t find any useful tool that’d support the Google Apps Scripts environment, so I decided to write one by myself.
In Leadfeeder for our Ruby apps, we use a great SaaS tool called Honeybadger which frees us from checking the logs every day and lets us just receive a Slack notification with error info right at the moment when something bad happens.
I’m a big fan of how simple and reliable Honeybadger is, so I quickly checked their API docs and decided that I’ll start building a client library to support Google Apps Scripts environment.

After a few days of TypeScript coding, I managed to create a version that satisfies my needs.
In the following paragraphs you’ll learn how to set up and use the library. Let me share my knowledge and work with you now :)

Installation

Add the library to your script

The library is already published as an Apps Script, making it easy to include in your project. To add it to your script, do the following in the Apps Script code editor:

Click on the menu item “Resources > Libraries…” In the “Find a Library” text box, enter the script ID M4hoogS1IHPlDGE3VXDWwuTI3yRUM8Pyy and click the "Select" button. Choose a version in the drop-down box (usually best to pick the latest version). Click the "Save" button.

Adjust your manifest file

  1. If you’re using explicit scopes in your Google Script’s manifest file ensure that googleapis.com/auth/script.external_request scope is included.

Setup the client

First, find your project’s API key on the following Honeybadger setting page:

Next, in your GAS function initialize the client by executing the following line:

Honeybadger.configure({
apiKey: '[ YOUR API KEY HERE ]'
});

Send error notifications to Honeybadger

Unfortunately, Google Apps Scripts don’t provide a way to catch all unhandled exceptions, so you will need to wrap your function’s code in try-catch like this:

function yourGasFunction() {
try {
// Your code
} catch(e) {
Honeybadger.notify(e);
}
}

Add execution context

You can pass additional context that will be sent alongside your notifications:

Honeybadger.context({
user_id: Session.getTemporaryActiveUserKey(),
user_email: Session.getActiveUser().getEmail()
});

Personally, I use the following helper function that does the initialization, adds execution context and sets up error handling at once:

function withHoneybadger(callback) {
const scriptProperties = PropertiesService.getScriptProperties();
const apiKey = scriptProperties.getProperty('HONEYBADGER_API_KEY');
Honeybadger.init({ apiKey: apiKey });
Honeybadger.context({
user_id: Session.getTemporaryActiveUserKey(),
user_locale: Session.getActiveUserLocale(),
user_email: Session.getActiveUser().getEmail()
});
try {
return callback();
} catch (e) {
Honeybadger.notify(e);
throw e;
}
}
function myGasFunction() {
return withHoneybadger(function() {
return gasFunctionLogic();
});
}

It works 🎉

I no more have to browse through the logs to find out that one of my scripts failed - the logs arrive at me automatically now :)

Here’s how an example error notification for my script looks like. You can find error’s stack trace, affected users, number of occurrences and the execution’s context at a quick glance.

Example error page created via honeybadger-gas library

Help & ideas welcome

The code of the library can be found in my GitHub repository: https://github.com/Bajena/honeybadger-gas. I encourage you to test it, let me know of any found bugs and give a helping hand if you have any improvement ideas.

Jan Bajena

Written by

Full stack developer @Leadfeeder. Hungry for knowledge and eager to learn new things. Languages of choice: Ruby & JS👨‍💻️