vwo-fme-ruby-sdk 1.6.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/resources/error_messages.json +46 -18
  3. data/lib/resources/info_messages.json +4 -2
  4. data/lib/vwo/api/get_flag.rb +13 -8
  5. data/lib/vwo/api/track_event.rb +2 -2
  6. data/lib/vwo/constants/constants.rb +24 -1
  7. data/lib/vwo/decorators/storage_decorator.rb +1 -5
  8. data/lib/vwo/enums/api_enum.rb +7 -3
  9. data/lib/vwo/enums/debug_category_enum.rb +20 -0
  10. data/lib/vwo/enums/event_enum.rb +1 -0
  11. data/lib/vwo/models/user/context_model.rb +36 -2
  12. data/lib/vwo/models/vwo_options_model.rb +14 -3
  13. data/lib/vwo/packages/network_layer/client/network_client.rb +189 -34
  14. data/lib/vwo/packages/network_layer/manager/network_manager.rb +71 -6
  15. data/lib/vwo/packages/network_layer/models/request_model.rb +38 -4
  16. data/lib/vwo/packages/network_layer/models/response_model.rb +10 -1
  17. data/lib/vwo/packages/segmentation_evaluator/core/segmentation_manager.rb +2 -1
  18. data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_evaluator.rb +5 -3
  19. data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_operand_evaluator.rb +3 -2
  20. data/lib/vwo/services/logger_service.rb +21 -1
  21. data/lib/vwo/services/settings_service.rb +37 -9
  22. data/lib/vwo/services/storage_service.rb +5 -4
  23. data/lib/vwo/utils/{batch_event_dispatcher.rb → batch_event_dispatcher_util.rb} +70 -9
  24. data/lib/vwo/utils/campaign_util.rb +35 -0
  25. data/lib/vwo/utils/debugger_service_util.rb +40 -0
  26. data/lib/vwo/utils/event_util.rb +8 -2
  27. data/lib/vwo/utils/function_util.rb +14 -0
  28. data/lib/vwo/utils/gateway_service_util.rb +5 -5
  29. data/lib/vwo/utils/impression_util.rb +16 -2
  30. data/lib/vwo/utils/meg_util.rb +29 -22
  31. data/lib/vwo/utils/network_util.rb +145 -38
  32. data/lib/vwo/utils/rule_evaluation_util.rb +1 -1
  33. data/lib/vwo/vwo_builder.rb +15 -11
  34. data/lib/vwo/vwo_client.rb +11 -25
  35. metadata +5 -4
  36. data/lib/vwo/utils/url_util.rb +0 -53
@@ -21,10 +21,12 @@ require_relative '../constants/constants'
21
21
  require_relative '../packages/network_layer/manager/network_manager'
22
22
  require_relative '../packages/network_layer/models/request_model'
23
23
  require_relative '../packages/network_layer/models/response_model'
24
- require_relative '../utils/url_util'
25
24
  require_relative '../utils/uuid_util'
26
25
  require_relative '../utils/usage_stats_util'
27
26
  require_relative '../models/user/context_model'
27
+ require_relative '../utils/log_message_util'
28
+ require_relative '../utils/function_util'
29
+ require_relative '../enums/api_enum'
28
30
 
29
31
  class NetworkUtil
30
32
  class << self
@@ -89,8 +91,7 @@ class NetworkUtil
89
91
  random: get_random_number,
90
92
  p: 'FS',
91
93
  visitor_ua: visitor_user_agent || '',
92
- visitor_ip: ip_address || '',
93
- url: "#{UrlUtil.get_base_url}#{UrlEnum::EVENTS}"
94
+ visitor_ip: ip_address || ''
94
95
  }
95
96
 
96
97
  if !is_usage_stats_event
@@ -260,37 +261,76 @@ class NetworkUtil
260
261
  end
261
262
 
262
263
  # Sends a POST API request with given properties and payload
263
- def send_post_api_request(properties, payload)
264
+ def send_post_api_request(properties, payload, campaign_info = {})
264
265
  network_instance = NetworkManager.instance
265
266
  headers = {}
266
267
  headers[HeadersEnum::USER_AGENT] = payload[:d][:visitor_ua] if payload[:d][:visitor_ua]
267
268
  headers[HeadersEnum::IP] = payload[:d][:visitor_ip] if payload[:d][:visitor_ip]
268
269
 
269
270
  request = RequestModel.new(
270
- UrlUtil.get_base_url,
271
+ SettingsService.instance.hostname,
271
272
  HttpMethodEnum::POST,
272
- UrlEnum::EVENTS,
273
+ SettingsService.instance.get_updated_endpoint_with_collection_prefix(UrlEnum::EVENTS),
273
274
  properties,
274
275
  payload,
275
276
  headers,
276
277
  SettingsService.instance.protocol,
277
278
  SettingsService.instance.port
278
279
  )
279
-
280
+
281
+ api_name = nil
282
+ extra_data_for_message = nil
283
+ if properties.key?(:en) && properties[:en] == EventEnum::VWO_VARIATION_SHOWN
284
+ api_name = ApiEnum::GET_FLAG
285
+ if campaign_info && campaign_info.key?(:campaign_type) && (campaign_info[:campaign_type] == CampaignTypeEnum::ROLLOUT || campaign_info[:campaign_type] == CampaignTypeEnum::PERSONALIZE)
286
+ extra_data_for_message = "feature: #{campaign_info[:feature_key]}, rule: #{campaign_info[:variation_name]}"
287
+ elsif campaign_info
288
+ extra_data_for_message = "feature: #{campaign_info[:feature_key]}, rule: #{campaign_info[:campaign_key]} and variation: #{campaign_info[:variation_name]}"
289
+ end
290
+ elsif properties.key?(:en) && properties[:en] != EventEnum::VWO_VARIATION_SHOWN
291
+ if properties.key?(:en) && properties[:en] == EventEnum::VWO_SYNC_VISITOR_PROP
292
+ api_name = ApiEnum::SET_ATTRIBUTE
293
+ extra_data_for_message = api_name
294
+ elsif properties.key?(:en) && properties[:en] != EventEnum::VWO_VARIATION_SHOWN && properties[:en] != EventEnum::VWO_DEBUGGER_EVENT && properties[:en] != EventEnum::VWO_INIT_CALLED
295
+ api_name = ApiEnum::TRACK_EVENT
296
+ extra_data_for_message = "event: #{properties[:en]}"
297
+ end
298
+ end
280
299
  begin
281
300
  if network_instance.get_client.get_should_use_threading
282
301
  network_instance.get_client.get_thread_pool.post {
283
302
  response = network_instance.post(request)
303
+ if response.get_total_attempts > 0
304
+ debug_event_props = create_network_and_retry_debug_event(response, request.get_body, api_name, extra_data_for_message)
305
+ debug_event_props[:uuid] = request.get_body[:d][:visId]
306
+ DebuggerServiceUtil.send_debugger_event(debug_event_props)
307
+ end
308
+ if response.get_status_code == 200
309
+ LoggerService.log(LogLevelEnum::INFO, "NETWORK_CALL_SUCCESS", {
310
+ event: properties[:en],
311
+ endPoint: UrlEnum::EVENTS,
312
+ accountId: SettingsService.instance.account_id,
313
+ uuid: request.get_body[:d][:visId]
314
+ })
315
+ end
284
316
  response
285
317
  }
286
318
  else
287
319
  response = network_instance.post(request)
320
+ if response.get_status_code == 200
321
+ LoggerService.log(LogLevelEnum::INFO, "NETWORK_CALL_SUCCESS", {
322
+ event: properties[:en],
323
+ endPoint: UrlEnum::EVENTS,
324
+ accountId: SettingsService.instance.account_id,
325
+ uuid: request.get_body[:d][:visId]
326
+ })
327
+ end
288
328
  response
289
329
  end
290
330
  rescue ResponseModel => err
291
331
  LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
292
- method: HttpMethodEnum::POST,
293
- err: err.is_a?(Hash) ? err.to_json : err
332
+ method: extra_data_for_message,
333
+ err: get_formatted_error_message(err.get_error)
294
334
  })
295
335
  end
296
336
  end
@@ -305,59 +345,126 @@ class NetworkUtil
305
345
  headers[HeadersEnum::USER_AGENT] = payload[:d][:visitor_ua] if payload[:d][:visitor_ua]
306
346
  headers[HeadersEnum::IP] = payload[:d][:visitor_ip] if payload[:d][:visitor_ip]
307
347
 
308
- url = Constants::HOST_NAME
309
- if UrlUtil.get_collection_prefix && !UrlUtil.get_collection_prefix.empty?
310
- url = "#{url}/#{UrlUtil.get_collection_prefix}"
311
- end
312
-
313
348
  request = RequestModel.new(
314
- url,
349
+ SettingsService.instance.hostname,
315
350
  HttpMethodEnum::POST,
316
- UrlEnum::EVENTS,
351
+ SettingsService.instance.get_updated_endpoint_with_collection_prefix(UrlEnum::EVENTS),
317
352
  properties,
318
353
  payload,
319
354
  headers,
320
- Constants::HTTPS_PROTOCOL,
321
- nil
355
+ SettingsService.instance.protocol,
356
+ SettingsService.instance.port,
322
357
  )
323
358
 
324
359
  begin
325
360
  if network_instance.get_client.get_should_use_threading
326
361
  network_instance.get_client.get_thread_pool.post {
327
362
  response = network_instance.post(request)
363
+ if response.get_status_code == 200
364
+ LoggerService.log(LogLevelEnum::INFO, "NETWORK_CALL_SUCCESS", {
365
+ event: properties[:en],
366
+ endPoint: UrlEnum::EVENTS,
367
+ accountId: SettingsService.instance.account_id,
368
+ uuid: request.get_body[:d][:visId]
369
+ })
370
+ end
328
371
  response
329
372
  }
330
373
  else
331
374
  response = network_instance.post(request)
375
+ if response.get_status_code == 200
376
+ LoggerService.log(LogLevelEnum::INFO, "NETWORK_CALL_SUCCESS", {
377
+ event: properties[:en],
378
+ endPoint: UrlEnum::EVENTS,
379
+ accountId: SettingsService.instance.account_id,
380
+ uuid: request.get_body[:d][:visId]
381
+ })
382
+ end
332
383
  response
333
384
  end
334
385
  rescue ResponseModel => err
386
+ if properties.key?(:en) && properties[:en] != EventEnum::VWO_DEBUGGER_EVENT
387
+ LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
388
+ method: "event: #{properties[:en]}",
389
+ err: get_formatted_error_message(err.get_error)
390
+ })
391
+ end
335
392
  end
336
393
  end
337
394
 
338
- # Sends a GET API request to the specified endpoint with given properties
339
- def send_get_api_request(properties, endpoint)
340
- network_instance = NetworkManager.instance
395
+ # get debugger event payload
396
+ def get_debugger_event_payload(event_props)
397
+ user_id = SettingsService.instance.account_id.to_s + "_" + SettingsService.instance.sdk_key
398
+ properties = _get_event_base_payload(user_id, EventEnum::VWO_DEBUGGER_EVENT, nil, nil)
399
+
400
+ # check if event_props contains uuid key and should be non null and non empty string
401
+ if event_props.key?(:uuid) && event_props[:uuid].is_a?(String) && !event_props[:uuid].empty?
402
+ properties[:d][:msgId] = "#{event_props[:uuid]}-#{get_current_unix_timestamp_in_millis}"
403
+ properties[:d][:visId] = event_props[:uuid]
404
+ else
405
+ event_props[:uuid] = properties[:d][:visId]
406
+ end
341
407
 
342
- request = RequestModel.new(
343
- UrlUtil.get_base_url,
344
- HttpMethodEnum::GET,
345
- endpoint,
346
- properties,
347
- nil,
348
- nil,
349
- SettingsService.Instance.protocol,
350
- SettingsService.Instance.port
351
- )
408
+ # check if event_props contains sessionId key
409
+ if event_props.key?(:sId)
410
+ properties[:d][:sessionId] = event_props[:sId]
411
+ else
412
+ event_props[:sId] = properties[:d][:sessionId]
413
+ end
352
414
 
353
- begin
354
- network_instance.get(request)
355
- rescue StandardError => err
356
- LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
357
- method: HttpMethodEnum::GET,
358
- err: err.is_a?(Hash) ? err.to_json : err
359
- })
415
+ event_props[:a] = SettingsService.instance.account_id.to_s
416
+ event_props[:product] = Constants::PRODUCT_NAME
417
+ event_props[:sn] = Constants::SDK_NAME
418
+ event_props[:sv] = Constants::SDK_VERSION
419
+ event_props[:eventId] = UUIDUtil.get_random_uuid(SettingsService.instance.sdk_key)
420
+
421
+ properties[:d][:event][:props] = {}
422
+ properties[:d][:event][:props][:vwoMeta] = event_props
423
+ properties
424
+ end
425
+
426
+ def create_network_and_retry_debug_event(response, payload, api_name, extra_data)
427
+ begin
428
+ category = DebugCategoryEnum::RETRY
429
+ msg_t = Constants::NETWORK_CALL_SUCCESS_WITH_RETRIES
430
+ msg = build_message(LoggerService.get_messages(LogLevelEnum::INFO)[msg_t], {
431
+ extraData: extra_data,
432
+ attempts: response.get_total_attempts,
433
+ err: get_formatted_error_message(response.get_error)
434
+ })
435
+ lt = LogLevelEnum::INFO.to_s
436
+ if response.get_status_code != 200
437
+ category = DebugCategoryEnum::NETWORK
438
+ msg_t = Constants::NETWORK_CALL_FAILURE_AFTER_MAX_RETRIES
439
+ msg = build_message(LoggerService.get_messages(LogLevelEnum::ERROR)[msg_t], {
440
+ extraData: extra_data,
441
+ attempts: response.get_total_attempts,
442
+ err: get_formatted_error_message(response.get_error)
443
+ })
444
+ lt = LogLevelEnum::ERROR.to_s
445
+ end
446
+ debug_event_props = {
447
+ cg: category,
448
+ msg_t: msg_t,
449
+ msg: msg,
450
+ lt: lt
451
+ }
452
+ if api_name
453
+ debug_event_props[:an] = api_name
360
454
  end
455
+
456
+ if payload && payload[:d] && payload[:d][:sessionId]
457
+ debug_event_props[:sId] = payload[:d][:sessionId]
458
+ else
459
+ debug_event_props[:sId] = get_current_unix_timestamp
460
+ end
461
+ debug_event_props
462
+ rescue StandardError => err
463
+ LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
464
+ method: extra_data,
465
+ err: get_formatted_error_message(err)
466
+ })
467
+ end
361
468
  end
362
469
  end
363
470
  end
@@ -49,7 +49,7 @@ def evaluate_rule(settings, feature, campaign, context, evaluated_feature_map, m
49
49
  )
50
50
 
51
51
  # Send an impression for the variation shown
52
- create_and_send_impression_for_variation_shown(settings, campaign.get_id, whitelisted_object[:variation_id], context)
52
+ create_and_send_impression_for_variation_shown(settings, campaign.get_id, whitelisted_object[:variation_id], context, feature.get_key)
53
53
  end
54
54
 
55
55
  # Return the results of the evaluation
@@ -23,9 +23,10 @@ require_relative './packages/segmentation_evaluator/core/segmentation_manager'
23
23
  require_relative './services/logger_service'
24
24
  require_relative './services/batch_event_queue'
25
25
  require_relative './utils/function_util'
26
- require_relative './utils/batch_event_dispatcher'
27
26
  require_relative './constants/constants'
28
27
  require_relative './utils/usage_stats_util'
28
+ require_relative './enums/api_enum'
29
+ require_relative './utils/batch_event_dispatcher_util'
29
30
 
30
31
  class VWOBuilder
31
32
  attr_reader :settings, :storage, :log_manager, :is_settings_fetch_in_progress, :vwo_instance, :is_valid_poll_interval_passed_from_init
@@ -61,7 +62,7 @@ class VWOBuilder
61
62
 
62
63
  if (!events_per_request.is_a?(Numeric) || events_per_request <= 0) &&
63
64
  (!request_time_interval.is_a?(Numeric) || request_time_interval <= 0)
64
- LoggerService.log(LogLevelEnum::ERROR, "INVALID_BATCH_EVENTS_CONFIG")
65
+ LoggerService.log(LogLevelEnum::ERROR, "INVALID_BATCH_EVENTS_CONFIG", { an: ApiEnum::INIT})
65
66
  end
66
67
 
67
68
  BatchEventsQueue.configure(
@@ -74,11 +75,11 @@ class VWOBuilder
74
75
  )
75
76
  @batch_event_data = @options[:batch_event_data]
76
77
  else
77
- LoggerService.log(LogLevelEnum::ERROR, "Invalid batch events config, should be a hash.", nil)
78
+ LoggerService.log(LogLevelEnum::ERROR, "INVALID_BATCH_EVENTS_CONFIG", { an: ApiEnum::INIT})
78
79
  end
79
80
  end
80
81
  rescue StandardError => e
81
- LoggerService.log(LogLevelEnum::ERROR, "Failed to initialize batch event queue: #{e.message}", nil)
82
+ LoggerService.log(LogLevelEnum::ERROR, "FAILED_TO_INITIALIZE_SERVICE", { service: 'Batch Event Queue', err: e.message, an: ApiEnum::INIT})
82
83
  end
83
84
  end
84
85
 
@@ -87,12 +88,14 @@ class VWOBuilder
87
88
  def set_network_manager
88
89
  begin
89
90
  network_instance = NetworkManager.instance(@options[:threading] || {})
90
- network_instance.attach_client(@options[:network][:client]) if @options[:network] && @options[:network][:client]
91
+ retry_config = @options[:retry_config]
92
+ client = (@options[:network] && @options[:network][:client]) ? @options[:network][:client] : nil
93
+ network_instance.attach_client(client, retry_config)
91
94
  LoggerService.log(LogLevelEnum::DEBUG, "SERVICE_INITIALIZED", {service: "Network Layer"})
92
95
  network_instance.get_config.set_development_mode(@options[:is_development_mode]) if @options[:is_development_mode]
93
96
  self
94
97
  rescue StandardError => e
95
- LoggerService.log(LogLevelEnum::ERROR, "Failed to initialize network manager: #{e.message}", nil)
98
+ LoggerService.log(LogLevelEnum::ERROR, "FAILED_TO_INITIALIZE_SERVICE", { service: 'Network Manager', err: e.message, an: ApiEnum::INIT})
96
99
  self
97
100
  end
98
101
  end
@@ -127,7 +130,7 @@ class VWOBuilder
127
130
  begin
128
131
  fetch_settings(force)
129
132
  rescue StandardError => e
130
- LoggerService.log(LogLevelEnum::ERROR, "Failed to fetch settings: #{e.message}", nil)
133
+ LoggerService.log(LogLevelEnum::ERROR, "ERROR_FETCHING_SETTINGS", { err: e.message, an: ApiEnum::INIT})
131
134
  {}
132
135
  end
133
136
  end
@@ -175,9 +178,10 @@ class VWOBuilder
175
178
  check_and_poll
176
179
  elsif poll_interval
177
180
  # only log error if poll_interval is present in options
178
- LoggerService.log(LogLevelEnum::ERROR, "INIT_OPTIONS_INVALID", {
181
+ LoggerService.log(LogLevelEnum::ERROR, "INVALID_POLLING_CONFIGURATION", {
179
182
  key: 'poll_interval',
180
- correctType: 'number >= 1000'
183
+ correctType: 'number >= 1000',
184
+ an: ApiEnum::INIT
181
185
  })
182
186
  end
183
187
  self
@@ -227,14 +231,14 @@ class VWOBuilder
227
231
  LoggerService.log(LogLevelEnum::INFO, "POLLING_NO_CHANGE_IN_SETTINGS")
228
232
  end
229
233
  rescue StandardError => e
230
- LoggerService.log(LogLevelEnum::ERROR, "POLLING_FETCH_SETTINGS_FAILED")
234
+ LoggerService.log(LogLevelEnum::ERROR, "ERROR_UPDATING_SETTINGS", { err: e.message, an: ApiEnum::INIT})
231
235
  end
232
236
  end
233
237
  end
234
238
  end
235
239
 
236
240
  def dispatcher(events, callback)
237
- BatchEventDispatcher.dispatch(
241
+ BatchEventDispatcherUtil.dispatch(
238
242
  {
239
243
  ev: events
240
244
  },
@@ -17,13 +17,13 @@ require_relative 'models/user/context_model'
17
17
  require_relative 'api/get_flag'
18
18
  require_relative 'api/set_attribute'
19
19
  require_relative 'api/track_event'
20
- require_relative 'utils/url_util'
21
20
  require_relative 'utils/settings_util'
22
21
  require_relative 'services/logger_service'
23
22
  require_relative 'enums/log_level_enum'
24
23
  require_relative 'utils/network_util'
25
24
  require_relative 'models/schemas/settings_schema_validation'
26
25
  require_relative 'services/batch_event_queue'
26
+ require_relative 'enums/api_enum'
27
27
 
28
28
  class VWOClient
29
29
  attr_accessor :settings, :original_settings
@@ -36,9 +36,8 @@ class VWOClient
36
36
 
37
37
  begin
38
38
  set_settings_and_add_campaigns_to_rules(settings, self)
39
- UrlUtil.init(collection_prefix: @settings.get_collection_prefix)
40
39
  rescue StandardError => e
41
- LoggerService.log(LogLevelEnum::ERROR, "Error setting and adding campaigns to rules message: #{e.message}", nil)
40
+ LoggerService.log(LogLevelEnum::ERROR, "ERROR_ADDING_CAMPAIGNS_TO_RULES", { err: e.message, an: ApiEnum::INIT})
42
41
  end
43
42
  LoggerService.log(LogLevelEnum::INFO, "CLIENT_INITIALIZED")
44
43
  self
@@ -57,26 +56,22 @@ class VWOClient
57
56
  LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
58
57
 
59
58
  unless feature_key.is_a?(String) && !feature_key.empty?
60
- LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'feature_key', type: feature_key.class.name , correctType: 'String'})
61
59
  raise TypeError, 'feature_key should be a non-empty string'
62
60
  end
63
61
  unless SettingsService.instance.is_settings_valid
64
- LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
65
62
  raise TypeError, 'Invalid Settings'
66
63
  end
67
64
  unless context.is_a?(Hash)
68
- LoggerService.log(LogLevelEnum::ERROR, "API_CONTEXT_INVALID")
69
65
  raise TypeError, 'Invalid context'
70
66
  end
71
67
  unless context[:id].is_a?(String) && !context[:id].empty?
72
- LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context.id', type: context[:id].class.name, correctType: 'String'})
73
68
  raise TypeError, 'Invalid context, id should be a non-empty string'
74
69
  end
75
70
 
76
71
  context_model = ContextModel.new.model_from_dictionary(context)
77
72
  FlagApi.new.get(feature_key, @settings, context_model, hooks_service)
78
73
  rescue StandardError => e
79
- LoggerService.log(LogLevelEnum::ERROR, "API_THROW_ERROR", {apiName: api_name, err: e.message})
74
+ LoggerService.log(LogLevelEnum::ERROR, "EXECUTION_FAILED", {apiName: api_name, err: e.message, an: ApiEnum::GET_FLAG})
80
75
  error_response
81
76
  end
82
77
  end
@@ -94,26 +89,22 @@ class VWOClient
94
89
  LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
95
90
 
96
91
  unless event_name.is_a?(String) && !event_name.empty?
97
- LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'event_name', type: event_name.class.name, correctType: 'String'})
98
92
  raise TypeError, 'event_name should be a non-empty string'
99
93
  end
100
94
  unless event_properties.is_a?(Hash)
101
- LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'event_properties', type: event_properties.class.name, correctType: 'Hash'})
102
95
  raise TypeError, 'event_properties should be a hash'
103
96
  end
104
97
  unless SettingsService.instance.is_settings_valid
105
- LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
106
98
  raise TypeError, 'Invalid Settings'
107
99
  end
108
100
  unless context[:id].is_a?(String) && !context[:id].empty?
109
- LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context.id', type: context[:id].class.name, correctType: 'String'})
110
101
  raise TypeError, 'Invalid context, id should be a non-empty string'
111
102
  end
112
103
 
113
104
  context_model = ContextModel.new.model_from_dictionary(context)
114
105
  TrackApi.new.track(@settings, event_name, context_model, event_properties, hooks_service)
115
106
  rescue StandardError => e
116
- LoggerService.log(LogLevelEnum::ERROR, "API_THROW_ERROR", {apiName: api_name, err: e.message})
107
+ LoggerService.log(LogLevelEnum::ERROR, "EXECUTION_FAILED", {apiName: api_name, err: e.message, an: ApiEnum::TRACK_EVENT})
117
108
  { event_name: false }
118
109
  end
119
110
  end
@@ -129,26 +120,22 @@ class VWOClient
129
120
  LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
130
121
 
131
122
  unless attributes.is_a?(Hash) && !attributes.empty?
132
- LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'attributes', type: attributes.class.name, correctType: 'Hash'})
133
123
  raise TypeError, 'Attributes should be a hash with key-value pairs and non-empty'
134
124
  end
135
125
  unless context.is_a?(Hash)
136
- LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context', type: context.class.name, correctType: 'Hash'})
137
126
  raise TypeError, 'Invalid context'
138
127
  end
139
128
  unless context[:id].is_a?(String) && !context[:id].empty?
140
- LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context.id', type: context[:id].class.name, correctType: 'String'})
141
129
  raise TypeError, 'Invalid context, id should be a non-empty string'
142
130
  end
143
131
  unless SettingsService.instance.is_settings_valid
144
- LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
145
132
  raise TypeError, 'Invalid Settings'
146
133
  end
147
134
 
148
135
  context_model = ContextModel.new.model_from_dictionary(context)
149
136
  SetAttributeApi.new.set_attribute(attributes, context_model)
150
137
  rescue StandardError => e
151
- LoggerService.log(LogLevelEnum::ERROR, "API_THROW_ERROR", {apiName: api_name, err: e.message})
138
+ LoggerService.log(LogLevelEnum::ERROR, "EXECUTION_FAILED", {apiName: api_name, err: e.message, an: ApiEnum::SET_ATTRIBUTE})
152
139
  end
153
140
  end
154
141
 
@@ -171,8 +158,7 @@ class VWOClient
171
158
 
172
159
  # Validate settings schema
173
160
  unless SettingsSchema.new.is_settings_valid(settings_to_update)
174
- LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
175
- raise TypeError, 'Invalid Settings'
161
+ raise TypeError, "Got Invalid Settings, settings: #{settings_to_update}"
176
162
  end
177
163
 
178
164
  # Set the settings on the client instance
@@ -181,12 +167,13 @@ class VWOClient
181
167
  rescue StandardError => e
182
168
  LoggerService.log(
183
169
  LogLevelEnum::ERROR,
184
- "SETTINGS_FETCH_FAILED",
170
+ "UPDATING_CLIENT_INSTANCE_FAILED_WHEN_WEBHOOK_TRIGGERED",
185
171
  {
186
172
  apiName: api_name,
187
173
  isViaWebhook: is_via_webhook,
188
- err: e.message
189
- }
174
+ err: e.message,
175
+ an: ApiEnum::UPDATE_SETTINGS
176
+ }, false
190
177
  )
191
178
  end
192
179
  end
@@ -198,14 +185,13 @@ class VWOClient
198
185
  begin
199
186
  LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
200
187
  if BatchEventsQueue.instance.nil?
201
- LoggerService.log(LogLevelEnum::ERROR, "Batching is not enabled. Pass batch_event_data in the SDK configuration while invoking init API.", nil)
202
188
  raise StandardError, "Batch events queue is not initialized"
203
189
  end
204
190
  # flush the batch events queue
205
191
  @response = BatchEventsQueue.instance.flush(true)
206
192
  @response
207
193
  rescue StandardError => e
208
- LoggerService.log(LogLevelEnum::ERROR, "API_THROW_ERROR", {apiName: api_name, err: e.message})
194
+ LoggerService.log(LogLevelEnum::ERROR, "EXECUTION_FAILED", {apiName: api_name, err: e.message, an: ApiEnum::FLUSH_EVENTS})
209
195
  end
210
196
  end
211
197
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vwo-fme-ruby-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VWO
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-12-09 00:00:00.000000000 Z
11
+ date: 2026-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uuidtools
@@ -155,6 +155,7 @@ files:
155
155
  - lib/vwo/decorators/storage_decorator.rb
156
156
  - lib/vwo/enums/api_enum.rb
157
157
  - lib/vwo/enums/campaign_type_enum.rb
158
+ - lib/vwo/enums/debug_category_enum.rb
158
159
  - lib/vwo/enums/decision_types_enum.rb
159
160
  - lib/vwo/enums/event_enum.rb
160
161
  - lib/vwo/enums/headers_enum.rb
@@ -207,9 +208,10 @@ files:
207
208
  - lib/vwo/services/logger_service.rb
208
209
  - lib/vwo/services/settings_service.rb
209
210
  - lib/vwo/services/storage_service.rb
210
- - lib/vwo/utils/batch_event_dispatcher.rb
211
+ - lib/vwo/utils/batch_event_dispatcher_util.rb
211
212
  - lib/vwo/utils/campaign_util.rb
212
213
  - lib/vwo/utils/data_type_util.rb
214
+ - lib/vwo/utils/debugger_service_util.rb
213
215
  - lib/vwo/utils/decision_util.rb
214
216
  - lib/vwo/utils/event_util.rb
215
217
  - lib/vwo/utils/function_util.rb
@@ -220,7 +222,6 @@ files:
220
222
  - lib/vwo/utils/network_util.rb
221
223
  - lib/vwo/utils/rule_evaluation_util.rb
222
224
  - lib/vwo/utils/settings_util.rb
223
- - lib/vwo/utils/url_util.rb
224
225
  - lib/vwo/utils/usage_stats_util.rb
225
226
  - lib/vwo/utils/uuid_util.rb
226
227
  - lib/vwo/vwo_builder.rb
@@ -1,53 +0,0 @@
1
- # Copyright 2024-2025 Wingify Software Pvt. Ltd.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- require_relative '../services/settings_service'
16
-
17
- class UrlUtil
18
- @collection_prefix = nil
19
-
20
- class << self
21
- attr_accessor :collection_prefix
22
-
23
- # Initializes the UrlUtil with an optional collection prefix.
24
- #
25
- # @param collection_prefix [String] Optional prefix for URL collections.
26
- # @return [UrlUtil] The singleton instance of UrlUtil with updated properties.
27
- def init(collection_prefix: nil)
28
- @collection_prefix = collection_prefix if collection_prefix.is_a?(String)
29
- self
30
- end
31
-
32
- # Retrieves the base URL.
33
- #
34
- # @return [String] The base URL.
35
- def get_base_url
36
- base_url = SettingsService.instance.hostname
37
-
38
- return base_url if SettingsService.instance.is_gateway_service_provided
39
-
40
- # Construct URL with collection_prefix if it exists
41
- return "#{base_url}/#{@collection_prefix}" if @collection_prefix
42
-
43
- base_url
44
- end
45
-
46
- # Retrieves the collection prefix.
47
- #
48
- # @return [String] The collection prefix.
49
- def get_collection_prefix
50
- @collection_prefix
51
- end
52
- end
53
- end