Error handling and messages for community connectors

To provide a good user experience it is important that you correctly handle errors that may occur with the use of your connector. This includes providing useful error messages for users so they know what caused the issue and any corrective steps that can be taken.

This document describes the types of errors that might occur with the use of your connector, how error messages work for connectors, and how to properly handle connector errors.

Types of errors

The types and causes of errors that a user may encounter when using your connector typically fall into one of the following three categories: Connector internal errors, connector external errors, and Data Studio errors.

Connector internal error

This is when an error occurs during the execution of your connector.

For example, if your connector does not correctly parse an API response during the execution of the getData function and fails, then this is considered a connector internal error.

The error displayed in Data Studio will include information such as the error message, error type and a stack trace showing where in your code the error occurred.

You should anticipate and handle connector errors like this in your code and provide user-friendly messages where applicable. For more information on handling connector errors, see Best practices for handling connector errors.

Connector external error

This is when your connector executed successfully but an error occurred during the processing of the connector response.

For example, if a getData request is made to your connector for 2 fields and your connector returns data for 3 fields, then this will result in an error. Although your connector executed successfully it did not satisfy the request properly and caused a connector external error in Data Studio.

The error message displayed in Data Studio may not contain any details.

You will need to review any error details (if available) and debug your code to identify and fix the issue with your connector. For more information on debugging your connector, see Debug your code.

Data Studio error

This is when an error occurs with Data Studio that is unrelated to your connector.

For example, if a user attempts to use a time series chart with a data source that has no date/time dimension then an error/warning will occur.

If the behavior or error is not directly related to your connector then there is no immediate action for you to take. Users can find additional help by visiting the Data Studio Help Center.

Error messages for admin users vs non-admin users

Rules for showing error details based on admin status

When a connector error occurs, the details shown to the user depends on the admin status of the user and the error message. The rules are as follows:

  • If the user is an admin user then they will see all details including the error message, type, and stack trace.
  • If the user is not an admin user then they will only see an error message if you have indicated the message is safe to display to non-admin users. To learn more about showing error messages to non-admin users see Throw error messages to non-Admin users.

Throwing error messages to non-Admin users

By default, only connector admin users see details such as error message, error type and the stack trace. This is to prevent any inadvertent disclosure of potentially sensitive connector details (e.g. A secret API key). However, you can use a special prefix to identify error messages that are safe to show to non-Admin users.

Use the DS_USER: prefix for safe error messages

To provide user-friendly error messages to non-admin users include the DS_USER: prefix with error messages. This prefix is used to identify safe messages for non-admin users and is not included in the actual error message.

The following examples include a case where an error message will be shown to non-admin users another where an error message will only be shown to admin users:

// Admin and non-admin users will see the following error.
try {
  // Code that might fail.
} catch (e) {
  throw new Error("DS_USER:This will be shown to admin & non-admin.");
}

// Only admin users will see the following error.
try {
  // Code that might fail.
} catch (e) {
  throw new Error("This message will only be shown to admin users");
}

Best practices for handling connector errors

You should attempt to catch and handle as many errors as possible during the execution of your connector code. For example, some common operations that may cause errors or an undesirable state include:

  • A failed URL fetch attempt (transient errors, timeouts).
  • No data available for the requested time period.
  • Data could not be parsed or formatted.
  • Auth tokens that have been revoked.

Handle recoverable errors

If there are points of connector execution that can fail but are recoverable then you should attempt to handle these cases. For example, if a function fetch fails for a non-fatal reason then you may want to retry at least 1 more time before throwing an error message that the execution failed.

Catch and throw errors

For fatal errors you should throw a user-friendly error message that will help users understand why the error occurred. If the underlying issue can likely be fixed then also provide some details on any corrective action they may be able to take to resolve the issue.

See Throw error messages to non-Admin users.

Log errors to Stackdriver

Consider using Stackdriver for logging errors and other messages. This can help you to easily identify errors and debug issues with your connector, including unhandled exceptions.

To learn more about Stackdriver error reporting, enabling exception logging for your script, and ways to safely identify users for debugging purposes see Using Stackdriver Logging.

Use a helper function to log and throw errors

It is recommended that you use a helper function to throw errors. This allows for consistent error handling and messaging and it will make it easy to incorporate any future changes to community connector error message capabilities.

Example helper function to throw errors:

  /**
   * Throws an error that complies with the community connector spec.
   * @param {string} message The error message.
   * @param {boolean} userSafe Determines whether this message is safe to show
   *     to non-admin users of the connector. true to show the message, false
   *     otherwise. false by default.
   */
  function throwConnectorError(message, userSafe) {
    userSafe = (typeof userSafe !== 'undefined' &&
                typeof userSafe === 'boolean') ?  userSafe : false;
    if (userSafe) {
      message = 'DS_USER:' + message;
    }

    throw new Error(message);
  }

Example helper function for logging:

  /**
   * Log an error that complies with the community connector spec.
   * @param {Error} originalError The original error that occurred.
   * @param {string} message Additional details about the error to include in
   *    the log entry.
   */
  function logConnectorError(originalError, message) {
    var logEntry = [
      'Original error (Message): ',
      originalError,
      '(', message, ')'
    ];
    console.error(logEntry.join('')); // Log to Stackdriver.
  }

Example of using the helper functions to throw and log error messages:

// Error message that will be shown to a non-admin users.
try {
  // Code that might fail.
} catch (e) {
  logConnectorError(e, 'quota_hour_exceeded'); // Log to Stackdriver.
  throwConnectorError("You've exceeded the hourly quota. Try again later.", true);
}