Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit d1af730

Browse files
Fault Treatment at entry points of SDK (optimizely#127)
1. Added try/catch blocks at the entry points in the SDK. 2. Added ErrorHandler and logging to all the catch blocks.
1 parent 6d6bb24 commit d1af730

File tree

4 files changed

+390
-293
lines changed

4 files changed

+390
-293
lines changed

packages/optimizely-sdk/lib/core/notification_center/index.js

Lines changed: 82 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ var MODULE_NAME = 'NOTIFICATION_CENTER';
3030
* @constructor
3131
* @param {Object} options
3232
* @param {Object} options.logger An instance of a logger to log messages with
33+
* @param {object} options.errorHandler An instance of errorHandler to handle any unexpected error
3334
* @returns {Object}
3435
*/
3536
function NotificationCenter(options) {
3637
this.logger = options.logger;
38+
this.errorHandler = options.errorHandler;
3739
this.__notificationListeners = {};
3840
fns.forOwn(enums.NOTIFICATION_TYPES, function(notificationTypeEnum) {
3941
this.__notificationListeners[notificationTypeEnum] = [];
@@ -51,36 +53,42 @@ function NotificationCenter(options) {
5153
* can happen if the first argument is not a valid notification type, or if the same callback
5254
* function was already added as a listener by a prior call to this function.
5355
*/
54-
NotificationCenter.prototype.addNotificationListener = function(notificationType, callback) {
55-
var isNotificationTypeValid = fns.values(enums.NOTIFICATION_TYPES)
56-
.indexOf(notificationType) > -1;
57-
if (!isNotificationTypeValid) {
58-
return -1;
59-
}
56+
NotificationCenter.prototype.addNotificationListener = function (notificationType, callback) {
57+
try {
58+
var isNotificationTypeValid = fns.values(enums.NOTIFICATION_TYPES)
59+
.indexOf(notificationType) > -1;
60+
if (!isNotificationTypeValid) {
61+
return -1;
62+
}
6063

61-
if (!this.__notificationListeners[notificationType]) {
62-
this.__notificationListeners[notificationType] = [];
63-
}
64+
if (!this.__notificationListeners[notificationType]) {
65+
this.__notificationListeners[notificationType] = [];
66+
}
6467

65-
var callbackAlreadyAdded = false;
66-
fns.forEach(this.__notificationListeners[notificationType], function(listenerEntry) {
67-
if (listenerEntry.callback === callback) {
68-
callbackAlreadyAdded = true;
69-
return false;
68+
var callbackAlreadyAdded = false;
69+
fns.forEach(this.__notificationListeners[notificationType], function (listenerEntry) {
70+
if (listenerEntry.callback === callback) {
71+
callbackAlreadyAdded = true;
72+
return false;
73+
}
74+
});
75+
if (callbackAlreadyAdded) {
76+
return -1;
7077
}
71-
});
72-
if (callbackAlreadyAdded) {
73-
return -1;
74-
}
7578

76-
this.__notificationListeners[notificationType].push({
77-
id: this.__listenerId,
78-
callback: callback,
79-
});
79+
this.__notificationListeners[notificationType].push({
80+
id: this.__listenerId,
81+
callback: callback,
82+
});
8083

81-
var returnId = this.__listenerId;
82-
this.__listenerId += 1;
83-
return returnId;
84+
var returnId = this.__listenerId;
85+
this.__listenerId += 1;
86+
return returnId;
87+
} catch (e) {
88+
this.logger.log(LOG_LEVEL.ERROR, e.message);
89+
this.errorHandler.handleError(e);
90+
return -1;
91+
}
8492
};
8593

8694
/**
@@ -89,45 +97,59 @@ NotificationCenter.prototype.addNotificationListener = function(notificationType
8997
* @returns {boolean} Returns true if the listener was found and removed, and false
9098
* otherwise.
9199
*/
92-
NotificationCenter.prototype.removeNotificationListener = function(listenerId) {
93-
var indexToRemove;
94-
var typeToRemove;
95-
fns.forOwn(this.__notificationListeners, function(listenersForType, notificationType) {
96-
fns.forEach(listenersForType, function(listenerEntry, i) {
97-
if (listenerEntry.id === listenerId) {
98-
indexToRemove = i;
99-
typeToRemove = notificationType;
100+
NotificationCenter.prototype.removeNotificationListener = function (listenerId) {
101+
try {
102+
var indexToRemove;
103+
var typeToRemove;
104+
fns.forOwn(this.__notificationListeners, function (listenersForType, notificationType) {
105+
fns.forEach(listenersForType, function (listenerEntry, i) {
106+
if (listenerEntry.id === listenerId) {
107+
indexToRemove = i;
108+
typeToRemove = notificationType;
109+
return false;
110+
}
111+
});
112+
if (indexToRemove !== undefined && typeToRemove !== undefined) {
100113
return false;
101114
}
102115
});
116+
103117
if (indexToRemove !== undefined && typeToRemove !== undefined) {
104-
return false;
118+
this.__notificationListeners[typeToRemove].splice(indexToRemove, 1);
119+
return true;
105120
}
106-
});
107-
108-
if (indexToRemove !== undefined && typeToRemove !== undefined) {
109-
this.__notificationListeners[typeToRemove].splice(indexToRemove, 1);
110-
return true;
121+
} catch (e) {
122+
this.logger.log(LOG_LEVEL.ERROR, e.message);
123+
this.errorHandler.handleError(e);
111124
}
112-
113125
return false;
114126
};
115127

116128
/**
117129
* Removes all previously added notification listeners, for all notification types
118130
*/
119-
NotificationCenter.prototype.clearAllNotificationListeners = function() {
120-
fns.forOwn(enums.NOTIFICATION_TYPES, function(notificationTypeEnum) {
121-
this.__notificationListeners[notificationTypeEnum] = [];
122-
}.bind(this));
131+
NotificationCenter.prototype.clearAllNotificationListeners = function () {
132+
try{
133+
fns.forOwn(enums.NOTIFICATION_TYPES, function (notificationTypeEnum) {
134+
this.__notificationListeners[notificationTypeEnum] = [];
135+
}.bind(this));
136+
} catch (e) {
137+
this.logger.log(LOG_LEVEL.ERROR, e.message);
138+
this.errorHandler.handleError(e);
139+
}
123140
};
124141

125142
/**
126143
* Remove all previously added notification listeners for the argument type
127144
* @param {string} notificationType One of enums.NOTIFICATION_TYPES
128145
*/
129-
NotificationCenter.prototype.clearNotificationListeners = function(notificationType) {
130-
this.__notificationListeners[notificationType] = [];
146+
NotificationCenter.prototype.clearNotificationListeners = function (notificationType) {
147+
try {
148+
this.__notificationListeners[notificationType] = [];
149+
} catch (e) {
150+
this.logger.log(LOG_LEVEL.ERROR, e.message);
151+
this.errorHandler.handleError(e);
152+
}
131153
};
132154

133155
/**
@@ -136,15 +158,20 @@ NotificationCenter.prototype.clearNotificationListeners = function(notificationT
136158
* @param {string} notificationType One of enums.NOTIFICATION_TYPES
137159
* @param {Object} notificationData Will be passed to callbacks called
138160
*/
139-
NotificationCenter.prototype.sendNotifications = function(notificationType, notificationData) {
140-
fns.forEach(this.__notificationListeners[notificationType], function(listenerEntry) {
141-
var callback = listenerEntry.callback;
142-
try {
143-
callback(notificationData);
144-
} catch (ex) {
145-
this.logger.log(LOG_LEVEL.ERROR, sprintf(LOG_MESSAGES.NOTIFICATION_LISTENER_EXCEPTION, MODULE_NAME, notificationType, ex.message));
146-
}
147-
}.bind(this));
161+
NotificationCenter.prototype.sendNotifications = function (notificationType, notificationData) {
162+
try {
163+
fns.forEach(this.__notificationListeners[notificationType], function (listenerEntry) {
164+
var callback = listenerEntry.callback;
165+
try {
166+
callback(notificationData);
167+
} catch (ex) {
168+
this.logger.log(LOG_LEVEL.ERROR, sprintf(LOG_MESSAGES.NOTIFICATION_LISTENER_EXCEPTION, MODULE_NAME, notificationType, ex.message));
169+
}
170+
}.bind(this));
171+
} catch (e) {
172+
this.logger.log(LOG_LEVEL.ERROR, e.message);
173+
this.errorHandler.handleError(e);
174+
}
148175
};
149176

150177
module.exports = {

packages/optimizely-sdk/lib/index.browser.js

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,36 +39,42 @@ module.exports = {
3939
* @return {Object} the Optimizely object
4040
*/
4141
createInstance: function(config) {
42-
var logLevel = 'logLevel' in config ? config.logLevel : enums.LOG_LEVEL.INFO;
43-
var defaultLogger = logger.createLogger({ logLevel: enums.LOG_LEVEL.INFO });
44-
if (config) {
45-
try {
46-
configValidator.validate(config);
47-
config.isValidInstance = true;
48-
} catch (ex) {
49-
var errorMessage = MODULE_NAME + ':' + ex.message;
50-
if (config.logger) {
51-
config.logger.log(enums.LOG_LEVEL.ERROR, errorMessage);
52-
} else {
53-
defaultLogger.log(enums.LOG_LEVEL.ERROR, errorMessage);
42+
try {
43+
var logLevel = 'logLevel' in config ? config.logLevel : enums.LOG_LEVEL.INFO;
44+
var defaultLogger = logger.createLogger({logLevel: enums.LOG_LEVEL.INFO});
45+
if (config) {
46+
try {
47+
configValidator.validate(config);
48+
config.isValidInstance = true;
49+
} catch (ex) {
50+
var errorMessage = MODULE_NAME + ':' + ex.message;
51+
if (config.logger) {
52+
config.logger.log(enums.LOG_LEVEL.ERROR, errorMessage);
53+
} else {
54+
defaultLogger.log(enums.LOG_LEVEL.ERROR, errorMessage);
55+
}
56+
config.isValidInstance = false;
5457
}
55-
config.isValidInstance = false;
5658
}
57-
}
5859

59-
// Explicitly check for null or undefined
60-
if (config.skipJSONValidation == null) { // eslint-disable-line eqeqeq
61-
config.skipJSONValidation = true;
62-
}
60+
// Explicitly check for null or undefined
61+
if (config.skipJSONValidation == null) { // eslint-disable-line eqeqeq
62+
config.skipJSONValidation = true;
63+
}
6364

64-
config = fns.assignIn({
65-
clientEngine: enums.JAVASCRIPT_CLIENT_ENGINE,
66-
clientVersion: enums.CLIENT_VERSION,
67-
errorHandler: defaultErrorHandler,
68-
eventDispatcher: defaultEventDispatcher,
69-
logger: logger.createLogger({ logLevel: logLevel })
70-
}, config);
65+
config = fns.assignIn({
66+
clientEngine: enums.JAVASCRIPT_CLIENT_ENGINE,
67+
clientVersion: enums.CLIENT_VERSION,
68+
errorHandler: defaultErrorHandler,
69+
eventDispatcher: defaultEventDispatcher,
70+
logger: logger.createLogger({logLevel: logLevel})
71+
}, config);
7172

72-
return new Optimizely(config);
73+
return new Optimizely(config);
74+
} catch (e) {
75+
config.logger.log(enums.LOG_LEVEL.ERROR, e.message);
76+
config.errorHandler.handleError(e);
77+
return null;
78+
}
7379
}
7480
};

0 commit comments

Comments
 (0)