diff --git a/app/assets/javascripts/app.ts b/app/assets/javascripts/app.ts
index dd0f8cb0a..9fdb061f2 100644
--- a/app/assets/javascripts/app.ts
+++ b/app/assets/javascripts/app.ts
@@ -53,6 +53,7 @@ import {
import { trusted } from './filters';
import { isDev } from './utils';
import { Bridge, BrowserBridge } from './services/bridge';
+import { startErrorReporting } from './services/errorReporting';
if (__WEB__) {
startApplication(
@@ -67,6 +68,7 @@ function startApplication(
defaultSyncServerHost: string,
bridge: Bridge
) {
+ startErrorReporting();
angular.module('app', ['ngSanitize']);
// Config
diff --git a/app/assets/javascripts/services/errorReporting.ts b/app/assets/javascripts/services/errorReporting.ts
new file mode 100644
index 000000000..3229051ab
--- /dev/null
+++ b/app/assets/javascripts/services/errorReporting.ts
@@ -0,0 +1,23 @@
+import { isDesktopApplication, isDev } from '@/utils';
+import { storage, StorageKey } from './localStorage';
+import Bugsnag from '@bugsnag/js';
+
+declare const __VERSION__: string;
+
+export async function startErrorReporting() {
+ if (storage.get(StorageKey.DisableErrorReporting)) {
+ return;
+ }
+ try {
+ Bugsnag.start({
+ apiKey: (window as any)._bugsnag_api_key,
+ appType: isDesktopApplication() ? 'desktop' : 'web',
+ appVersion: __VERSION__,
+ collectUserIp: false,
+ autoTrackSessions: false,
+ releaseStage: isDev ? 'development' : undefined
+ });
+ } catch (error) {
+ console.error('Failed to start Bugsnag.', error);
+ }
+}
diff --git a/app/assets/javascripts/services/localStorage.ts b/app/assets/javascripts/services/localStorage.ts
new file mode 100644
index 000000000..5f832ea00
--- /dev/null
+++ b/app/assets/javascripts/services/localStorage.ts
@@ -0,0 +1,16 @@
+export enum StorageKey {
+ DisableErrorReporting = 'DisableErrorReporting',
+}
+
+export const storage = {
+ get(key: StorageKey) {
+ const value = localStorage.getItem(key);
+ return value ? JSON.parse(value) : null;
+ },
+ set(key: StorageKey, value: unknown) {
+ localStorage.setItem(key, JSON.stringify(value));
+ },
+ remove(key: StorageKey) {
+ localStorage.removeItem(key);
+ },
+};
diff --git a/app/views/application/app.html.erb b/app/views/application/app.html.erb
index 724234545..71d29c6bb 100644
--- a/app/views/application/app.html.erb
+++ b/app/views/application/app.html.erb
@@ -32,6 +32,7 @@
window._default_sync_server = "<%= ENV['SF_DEFAULT_SERVER'] %>";
window._extensions_manager_location = "<%= ENV['EXTENSIONS_MANAGER_LOCATION'] %>";
window._batch_manager_location = "<%= ENV['BATCH_MANAGER_LOCATION'] %>";
+ window._bugsnag_api_key = "<%= ENV['BUGSNAG_API_KEY'] %>";
<% if Rails.env.development? %>
diff --git a/index.html b/index.html
index 4f5967139..01ac2ef10 100644
--- a/index.html
+++ b/index.html
@@ -32,11 +32,13 @@
data-default-sync-server="<%= env.DEV_DEFAULT_SYNC_SERVER %>"
data-extensions-manager-location="<%= env.DEV_EXTENSIONS_MANAGER_LOCATION %>"
data-batch-manager-location="<%= env.DEV_BATCH_MANAGER_LOCATION %>"
+ data-bugsnag-api-key="<%= env.DEV_BUGSNAG_API_KEY %>"
>