huginn_bigcommerce_product_agent 2.0.0 → 2.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2d3a13bdac789b3b1714c68e8794c30f0f15390c0161dd8a473d36f097f4422
4
- data.tar.gz: ecc6fe4feb48b5bf7d8528951fd0bcccd41b095f9b1070f73e4d41b5b31908cd
3
+ metadata.gz: af097d968dbd6e4c5b16bd27be4b48a685625056f23e4863e749b8e2382ee06f
4
+ data.tar.gz: e441b45253fde8999a4480bf2f9dbd419cd228d21c3e05dad47d45d8f4dbbe08
5
5
  SHA512:
6
- metadata.gz: db7b3003393f5b1c4e741a6be04b3bfb8bfd7be7aaf0cd006d7dd03112da997edb0efac33f2d5e41d5bc1f2d128a67c6be5c68b76b9be9b20bad4e7fbc397680
7
- data.tar.gz: 1d18a0e667d3216a194816ded4f4c523dffe4eeda9d7a84186285f6a6e53ea4d14f2f8e28b2333b5de65b517e5e1bb2149c77cd7a53f659f8a65e352b266257a
6
+ metadata.gz: c8fc484fc9c277ce1deb6b1ec3baed84f74a607e12b2667eb4fcfc5c160511623364d9c8d962f3367f713fd1da6b430da128160a45a5f575badfd5efb01f6af6
7
+ data.tar.gz: 8546a2251a5a077eb00ad8cbbf9aa605b121ce251565121f5a36bdffa65099f1e67e26f217a7f64b0ada326410cfa271b459945fdadc02ac5f0e68cc8b46a1c5
@@ -33,7 +33,17 @@ module BigcommerceProductAgent
33
33
  begin
34
34
  client.delete(uri(product_id: product_id, custom_field_id: custom_field_id))
35
35
  rescue Faraday::Error::ClientError => e
36
- raise e, "\n#{e.message}\nFailed to delete custom_field with id = #{custom_field_id}\nfor product with id = #{product_id}\n", e.backtrace
36
+ raise BigCommerceProductError.new(
37
+ e.response[:status],
38
+ 'delete custom field',
39
+ 'Failed to delete custom field',
40
+ product_id,
41
+ {
42
+ custom_field_id: custom_field_id,
43
+ errors: JSON.parse(e.response[:body])['errors']
44
+ },
45
+ e
46
+ )
37
47
  end
38
48
  end
39
49
 
@@ -46,8 +56,19 @@ module BigcommerceProductAgent
46
56
  return create(product_id, payload)
47
57
  end
48
58
  rescue Faraday::Error::ClientError => e
49
- puts e.inspect
50
- raise e
59
+ # include the field ID and name in the error here as _create_ requests have no ID
60
+ raise BigCommerceProductError.new(
61
+ e.response[:status],
62
+ 'upsert custom field',
63
+ 'Failed to delete custom field',
64
+ product_id,
65
+ {
66
+ custom_field_id: payload['id'],
67
+ field_name: payload[:name],
68
+ errors: JSON.parse(e.response[:body])['errors']
69
+ },
70
+ e
71
+ )
51
72
  end
52
73
  end
53
74
  end
@@ -39,8 +39,19 @@ module BigcommerceProductAgent
39
39
  return create(product_id, meta_field)
40
40
  end
41
41
  rescue Faraday::Error::ClientError => e
42
- puts e.inspect
43
- raise e
42
+ # include the field ID and name in the error here as _create_ requests have no ID
43
+ raise BigCommerceProductError.new(
44
+ e.response[:status],
45
+ 'upsert meta field',
46
+ 'Failed to upsert meta field field',
47
+ product_id,
48
+ {
49
+ meta_field_id: meta_field['id'],
50
+ field_name: meta_field['key'],
51
+ errors: JSON.parse(e.response[:body])['errors'],
52
+ },
53
+ e
54
+ )
44
55
  end
45
56
  end
46
57
 
@@ -48,7 +59,17 @@ module BigcommerceProductAgent
48
59
  begin
49
60
  client.delete(uri(product_id: product_id, meta_field_id: meta_field_id))
50
61
  rescue Faraday::Error::ClientError => e
51
- raise e, "\n#{e.message}\nFailed to delete meta_field with id = #{meta_field_id}\nfor product with id = #{product_id}\n", e.backtrace
62
+ raise BigCommerceProductError.new(
63
+ e.response[:status],
64
+ 'delete meta field',
65
+ 'Failed to delete meta field',
66
+ product_id,
67
+ {
68
+ meta_field_id: meta_field_id,
69
+ errors: JSON.parse(e.response[:body])['errors'],
70
+ },
71
+ e
72
+ )
52
73
  end
53
74
  end
54
75
  end
@@ -11,7 +11,17 @@ module BigcommerceProductAgent
11
11
 
12
12
  return response.body['data']
13
13
  rescue Faraday::Error::ClientError => e
14
- raise e, "\n#{e.message}\nFailed to update product with payload = #{payload.to_json}\n", e.backtrace
14
+ raise BigCommerceProductError.new(
15
+ e.response[:status],
16
+ 'update product',
17
+ 'Failed to update product',
18
+ id,
19
+ {
20
+ sku: payload[:sku],
21
+ errors: JSON.parse(e.response[:body])['errors'],
22
+ },
23
+ e
24
+ )
15
25
  end
16
26
  end
17
27
 
@@ -23,7 +33,18 @@ module BigcommerceProductAgent
23
33
 
24
34
  return response.body['data']
25
35
  rescue Faraday::Error::ClientError => e
26
- raise e, "\n#{e.message}\nFailed to update product batch with payload = #{payload.to_json}\n", e.backtrace
36
+ raise BigCommerceProductError.new(
37
+ e.response[:status],
38
+ 'update product',
39
+ 'Failed to update product batch',
40
+ {
41
+ product_identifiers: payload.map { |p|
42
+ { id: p[:id], sku: p[:sku] }
43
+ },
44
+ errors: JSON.parse(e.response[:body])['errors'],
45
+ },
46
+ e
47
+ )
27
48
  end
28
49
  end
29
50
 
@@ -40,7 +61,26 @@ module BigcommerceProductAgent
40
61
 
41
62
  return response.body['data']
42
63
  rescue Faraday::Error::ClientError => e
43
- raise e, "\n#{e.message}\nFailed to create product with payload = #{payload.to_json}\n", e.backtrace
64
+
65
+ Rails.logger.info('RESPONSE OBJECT: ------------------------------------------')
66
+ Rails.logger.info(e.response.inspect)
67
+ Rails.logger.info('------------------------------------------------------------')
68
+
69
+ Rails.logger.info('RESPONSE METHODS: -----------------------------------------')
70
+ Rails.logger.info(e.response.methods)
71
+ Rails.logger.info('------------------------------------------------------------')
72
+
73
+ raise BigCommerceProductError.new(
74
+ e.response[:status],
75
+ 'create product',
76
+ 'Failed to create product',
77
+ nil,
78
+ {
79
+ sku: payload[:sku],
80
+ errors: JSON.parse(e.response[:body])['errors'],
81
+ },
82
+ e
83
+ )
44
84
  end
45
85
  end
46
86
 
@@ -55,11 +95,30 @@ module BigcommerceProductAgent
55
95
 
56
96
  # When using sku:in you must specify the fields you want returned.
57
97
  def get_by_skus(skus, include = %w[custom_fields modifiers], include_fields = %w[sku])
58
- products = index({
59
- 'sku:in': skus.join(','),
60
- include: include.join(','),
61
- include_fields: include_fields.join(','),
62
- })
98
+ products = []
99
+ skus.each do |sku|
100
+ begin
101
+ data = index({
102
+ 'sku': sku,
103
+ include: include.join(','),
104
+ include_fields: include_fields.join(','),
105
+ })
106
+ if not data.empty?
107
+ products.push(data[0])
108
+ end
109
+ rescue Faraday::Error::ClientError => e
110
+ raise BigCommerceProductError.new(
111
+ e.response[:status],
112
+ 'get by sku',
113
+ 'Failed to get existing product data',
114
+ sku,
115
+ {
116
+ related_skus: skus,
117
+ errors: JSON.parse(e.response[:body])['errors'],
118
+ }
119
+ )
120
+ end
121
+ end
63
122
 
64
123
  return products
65
124
  end
@@ -12,4 +12,5 @@ Dir[File.join(__dir__, 'mapper', '*.rb')].each do |file|
12
12
  HuginnAgent.load file
13
13
  end
14
14
 
15
+ HuginnAgent.load 'huginn_bigcommerce_product_agent/big_commerce_product_error'
15
16
  HuginnAgent.register 'huginn_bigcommerce_product_agent/bigcommerce_product_agent'
@@ -0,0 +1,13 @@
1
+ class BigCommerceProductError < StandardError
2
+ attr_reader :status, :scope, :product_identifier, :data, :original_error
3
+
4
+ def initialize(status, scope, message, product_identifier, data, original_error)
5
+ @status = status
6
+ @scope = scope
7
+ @product_identifier = product_identifier
8
+ @data = data
9
+ @original_error = original_error
10
+
11
+ super(message)
12
+ end
13
+ end
@@ -185,13 +185,12 @@ module Agents
185
185
  bc_products = @product_client.get_by_skus(raw_products.map { |r| r['sku'] })
186
186
 
187
187
  return bc_products
188
- rescue => e
188
+ rescue BigCommerceProductError => e
189
189
  create_event payload: {
190
- status: 500,
191
- scope: 'lookup_existing_products',
190
+ status: e.status,
191
+ scope: e.scope,
192
192
  message: e.message,
193
- trace: e.backtrace.join('\n'),
194
- raw_product: raw_products,
193
+ data: e.data,
195
194
  }
196
195
 
197
196
  raise e
@@ -206,14 +205,17 @@ module Agents
206
205
  def delete_inactive_product(bc_product)
207
206
  begin
208
207
  @product_client.delete(bc_product['id'])
208
+ rescue BigCommerceProductError => e
209
+ emit_error(e)
209
210
  rescue => e
210
- create_event payload: {
211
- status: 500,
212
- scope: 'delete_inactive_product',
213
- message: e.message,
214
- trace: e.backtrace.join('\n'),
215
- bc_product: bc_product,
216
- }
211
+ emit_error(BigCommerceProductError.new(
212
+ 500,
213
+ 'delete inactive_product',
214
+ e.message,
215
+ bc_product['id'],
216
+ { sku: bc_product['sku'] },
217
+ e,
218
+ ))
217
219
  end
218
220
  end
219
221
 
@@ -224,18 +226,20 @@ module Agents
224
226
  custom_fields = map_custom_fields(raw_product, nil)
225
227
  bc_payload['custom_fields'] = custom_fields[:upsert]
226
228
  return @product_client.create(bc_payload, { include: 'custom_fields' })
229
+ rescue BigCommerceProductError => e
230
+ emit_error(e)
227
231
  rescue => e
228
- create_event payload: {
229
- status: 500,
230
- scope: 'create_product',
231
- message: e.message(),
232
- trace: e.backtrace.join('\n'),
233
- raw_product: raw_product,
234
- product_data: bc_payload,
235
- }
236
-
237
- return nil
232
+ emit_error(BigCommerceProductError.new(
233
+ 500,
234
+ 'create_new_product',
235
+ e.message,
236
+ nil,
237
+ { sku: raw_product['sku'] },
238
+ e
239
+ ))
238
240
  end
241
+
242
+ return nil
239
243
  end
240
244
 
241
245
  # Generates an update payload for the provided product records
@@ -247,15 +251,17 @@ module Agents
247
251
  begin
248
252
  # Delete custom fields that are no longer used
249
253
  @custom_field_client.delete(bc_product['id'], field['id'])
254
+ rescue BigCommerceProductError => e
255
+ emit_error(e)
250
256
  rescue => e
251
- create_event payload: {
252
- status: 500,
253
- scope: 'delete_custom_fields',
254
- message: e.message(),
255
- trace: e.backtrace.join('\n'),
256
- product_id: bc_product['id'],
257
- deletes: custom_fields[:delete]
258
- }
257
+ emit_error(BigCommerceProductError.new(
258
+ 500,
259
+ 'delete_custom_fields',
260
+ e.message,
261
+ bc_product['id'],
262
+ { sku: bc_product['sku'], field_id: field['id'] },
263
+ e
264
+ ))
259
265
  end
260
266
  end
261
267
 
@@ -316,14 +322,17 @@ module Agents
316
322
  status: 200,
317
323
  }
318
324
  end
325
+ rescue BigCommerceProductError => e
326
+ emit_error(e)
319
327
  rescue => e
320
- create_event payload: {
321
- status: 500,
322
- scope: 'upsert_products',
323
- message: e.message,
324
- trace: e.backtrace.join('\n'),
325
- product_data: product_data,
326
- }
328
+ emit_error(BigCommerceProductError.new(
329
+ 500,
330
+ 'upsert_products',
331
+ e.message,
332
+ nil,
333
+ { sku: product_data.map { |p| p['sku'] } },
334
+ e
335
+ ))
327
336
  end
328
337
  end
329
338
 
@@ -354,14 +363,17 @@ module Agents
354
363
  end
355
364
 
356
365
  return bc_payload
366
+ rescue BigCommerceProductError => e
367
+ emit_error(e)
357
368
  rescue => e
358
- create_event payload: {
359
- status: 500,
360
- scope: 'map_product',
361
- message: e.message(),
362
- trace: e.backtrace.join('\n'),
363
- product_payload: bc_payload,
364
- }
369
+ emit_error(BigCommerceProductError.new(
370
+ 500,
371
+ 'map_product',
372
+ e.message,
373
+ bc_product['id'],
374
+ { sku: bc_product['sku'] },
375
+ e
376
+ ))
365
377
  end
366
378
 
367
379
  return nil
@@ -375,19 +387,20 @@ module Agents
375
387
 
376
388
  begin
377
389
  return get_mapper(:CustomFieldMapper).map(options['custom_fields_map'], raw_product, bc_payload, current_fields, options['meta_fields_namespace'])
390
+ rescue BigCommerceProductError => e
391
+ emit_error(e)
378
392
  rescue => e
379
- create_event payload: {
380
- status: 500,
381
- scope: 'map_custom_fields',
382
- message: e.message(),
383
- trace: e.backtrace.join('\n'),
384
- field_map: options['custom_fields_map'],
385
- raw_product: raw_product,
386
- product_payload: bc_payload,
387
- }
388
-
389
- return nil
393
+ emit_error(BigCommerceProductError.new(
394
+ 500,
395
+ 'map_custom_fields',
396
+ e.message,
397
+ bc_payload['id'],
398
+ { sku: bc_payload['sku'] },
399
+ e
400
+ ))
390
401
  end
402
+
403
+ return nil
391
404
  end
392
405
 
393
406
  # Manages meta field values for the provided product records.
@@ -398,15 +411,18 @@ module Agents
398
411
 
399
412
  begin
400
413
  current_fields = @meta_field_client.get_for_product(bc_payload['id'])
414
+ rescue BigCommerceProductError => e
415
+ emit_error(e)
416
+ return nil
401
417
  rescue => e
402
- create_event payload: {
403
- status: 500,
404
- scope: 'update_meta_fields',
405
- message: "Failed to lookup existing meta fields: #{e.message()}",
406
- trace: e.backtrace.join('\n'),
407
- product_id: bc_payload['id'],
408
- }
409
-
418
+ emit_error(BigCommerceProductError.new(
419
+ 500,
420
+ 'get_meta_fields',
421
+ e.message,
422
+ bc_payload['id'],
423
+ { sku: bc_payload['sku'] },
424
+ e
425
+ ))
410
426
  return nil
411
427
  end
412
428
 
@@ -417,15 +433,17 @@ module Agents
417
433
  fields[:delete].each do |field|
418
434
  begin
419
435
  @meta_field_client.delete(bc_payload['id'], field['id'])
436
+ rescue BigCommerceProductError => e
437
+ emit_error(e)
420
438
  rescue => e
421
- create_event payload: {
422
- status: 500,
423
- scope: 'update_meta_fields',
424
- message: "Failed to delete meta field: #{e.message()}",
425
- trace: e.backtrace.join('\n'),
426
- product_id: bc_payload['id'],
427
- field: field,
428
- }
439
+ emit_error(BigCommerceProductError.new(
440
+ 500,
441
+ 'delete meta_fields',
442
+ e.message,
443
+ bc_payload['id'],
444
+ { sku: bc_payload['sku'] },
445
+ e
446
+ ))
429
447
  end
430
448
  end
431
449
 
@@ -433,33 +451,35 @@ module Agents
433
451
  fields[:upsert].each do |field|
434
452
  begin
435
453
  @meta_field_client.upsert(bc_payload['id'], field)
454
+ rescue BigCommerceProductError => e
455
+ emit_error(e)
436
456
  rescue => e
437
- create_event payload: {
438
- status: 500,
439
- scope: 'update_meta_fields',
440
- message: "Failed to update meta field: #{e.message()}",
441
- trace: e.backtrace.join('\n'),
442
- product_id: bc_payload['id'],
443
- field: field,
444
- }
457
+ emit_error(BigCommerceProductError.new(
458
+ 500,
459
+ 'upsert_meta_fields',
460
+ e.message,
461
+ bc_payload['id'],
462
+ { sku: bc_payload['sku'] },
463
+ e
464
+ ))
445
465
  end
446
466
  end
447
467
 
448
468
  return fields
469
+ rescue BigCommerceProductError => e
470
+ emit_error(e)
449
471
  rescue => e
450
- create_event payload: {
451
- status: 500,
452
- scope: 'update_meta_fields',
453
- message: "Failed to map meta field data: #{e.message()}",
454
- trace: e.backtrace.join('\n'),
455
- field_map: options['meta_fields_map'],
456
- raw_product: raw_product,
457
- bc_payload: bc_payload,
458
- current_fields: current_fields,
459
- }
460
-
461
- return nil
472
+ emit_error(BigCommerceProductError.new(
473
+ 500,
474
+ 'map_meta_fields',
475
+ e.message,
476
+ bc_payload['id'],
477
+ { sku: bc_payload['sku'] },
478
+ e
479
+ ))
462
480
  end
481
+
482
+ return nil
463
483
  end
464
484
 
465
485
  private
@@ -482,5 +502,26 @@ module Agents
482
502
  def get_mapper(class_name)
483
503
  return ::BigcommerceProductAgent::Mapper.const_get(class_name.to_sym)
484
504
  end
505
+
506
+ # Takes a BigCommerceProductError and emits the underlying data as an error payload
507
+ # to assist with error reporting. It is recommended that these errors be consolidated
508
+ # with a Digest Agent and reported as a summary.
509
+ def emit_error(error)
510
+
511
+ payload = {
512
+ status: error.status,
513
+ message: error.message,
514
+ scope: error.scope,
515
+ product_identifier: error.product_identifier,
516
+ data: error.data,
517
+ }
518
+
519
+ Rails.logger.debug({
520
+ error: payload,
521
+ trace: error.backtrace
522
+ })
523
+
524
+ create_event({ payload: payload })
525
+ end
485
526
  end
486
527
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: huginn_bigcommerce_product_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Spizziri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-24 00:00:00.000000000 Z
11
+ date: 2021-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -65,6 +65,7 @@ files:
65
65
  - lib/client/meta_field.rb
66
66
  - lib/client/product.rb
67
67
  - lib/huginn_bigcommerce_product_agent.rb
68
+ - lib/huginn_bigcommerce_product_agent/big_commerce_product_error.rb
68
69
  - lib/huginn_bigcommerce_product_agent/bigcommerce_product_agent.rb
69
70
  - lib/mapper/custom_field_mapper.rb
70
71
  - lib/mapper/meta_field_mapper.rb