zuora_connect 2.0.5zz → 2.0.5

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.
data/lib/zuora_connect.rb CHANGED
@@ -2,6 +2,7 @@ require 'zuora_connect/configuration'
2
2
  require "zuora_connect/engine"
3
3
  require 'zuora_connect/exceptions'
4
4
  require 'zuora_connect/controllers/helpers'
5
+ require 'zuora_connect/views/helpers'
5
6
  require 'zuora_connect/railtie'
6
7
  require 'resque/additions'
7
8
  require 'resque/dynamic_queues'
@@ -24,49 +25,30 @@ module ZuoraConnect
24
25
  else
25
26
  @logger ||= custom_logger(name: "Connect", level: Rails.logger.level)
26
27
  end
27
- end
28
+ end
28
29
 
29
30
  def custom_logger(name: "", level: Rails.logger.present? ? Rails.logger.level : MonoLogger::INFO, type: :ougai)
30
31
  #puts name + ' - ' + {Logger::WARN => 'Logger::WARN', Logger::ERROR => 'Logger::ERROR', Logger::DEBUG => 'Logger::DEBUG', Logger::INFO => 'Logger::INFO' }[level] + ' - '
31
32
  if type == :ougai
32
33
  require 'ougai'
33
- require "ougai/formatters/customizable"
34
34
  #logger = Ougai::Logger.new(MonoLogger.new(STDOUT))
35
- logger = Ougai::Logger.new(STDOUT)
35
+ logger = Ougai::Logger.new(STDOUT)
36
+ logger.formatter = Ougai::Formatters::ConnectFormatter.new(name)
36
37
  logger.level = level
37
- if ZuoraConnect.configuration.json_logging
38
- logger.formatter = Ougai::Formatters::ConnectFormatter.new(name)
39
- logger.before_log = lambda do |data|
40
- data[:trace_id] = ZuoraConnect::RequestIdMiddleware.request_id if ZuoraConnect::RequestIdMiddleware.request_id.present?
41
- data[:zuora_trace_id] = ZuoraConnect::RequestIdMiddleware.zuora_request_id if ZuoraConnect::RequestIdMiddleware.zuora_request_id.present?
42
- #data[:traces] = {amazon_id: data[:trace_id], zuora_id: data[:zuora_trace_id]}
43
- if !['ElasticAPM', 'ResqueScheduler', 'ResquePool', 'Resque', 'Makara'].include?(name)
44
- if Thread.current[:appinstance].present?
45
- data[:app_instance_id] = Thread.current[:appinstance].id
46
- logitems = Thread.current[:appinstance].logitems
47
- if logitems.present? && logitems.class == Hash
48
- data[:tenant_ids] = logitems[:tenant_ids] if logitems[:tenant_ids].present?
49
- data[:organization] = logitems[:organization] if logitems[:organization].present?
50
- end
38
+ logger.before_log = lambda do |data|
39
+ data[:trace_id] = ZuoraConnect::RequestIdMiddleware.request_id if ZuoraConnect::RequestIdMiddleware.request_id.present?
40
+ data[:zuora_trace_id] = ZuoraConnect::RequestIdMiddleware.zuora_request_id if ZuoraConnect::RequestIdMiddleware.zuora_request_id.present?
41
+ #data[:traces] = {amazon_id: data[:trace_id], zuora_id: data[:zuora_trace_id]}
42
+ if !['ElasticAPM', 'ResqueScheduler', 'ResquePool', 'Resque', 'Makara'].include?(name)
43
+ if Thread.current[:appinstance].present?
44
+ data[:app_instance_id] = Thread.current[:appinstance].id
45
+ logitems = Thread.current[:appinstance].logitems
46
+ if logitems.present? && logitems.class == Hash
47
+ data[:tenant_ids] = logitems[:tenant_ids] if logitems[:tenant_ids].present?
48
+ data[:organization] = logitems[:organization] if logitems[:organization].present?
51
49
  end
52
50
  end
53
51
  end
54
- else
55
- logger.formatter = Ougai::Formatters::Customizable.new(
56
- format_err: proc do |data|
57
- next nil unless data.key?(:err)
58
- err = data.delete(:err)
59
- " #{err[:name]} (#{err[:message]})\n #{err[:stack]}"
60
- end,
61
- format_data: proc do |data|
62
- format('%s %s: %s', 'DATA'.ljust(6), Time.now.strftime('%FT%T.%6NZ'), "#{data.to_json}") if data.present?
63
- end,
64
- format_msg: proc do |severity, datetime, _progname, data|
65
- msg = data.delete(:msg)
66
- format('%s %s: %s', severity.ljust(6), datetime, msg)
67
- end
68
- )
69
- logger.formatter.datetime_format = '%FT%T.%6NZ'
70
52
  end
71
53
  else
72
54
  logger = MonoLogger.new(STDOUT)
@@ -76,39 +58,40 @@ module ZuoraConnect
76
58
  msg = JSON.parse(msg)
77
59
  rescue JSON::ParserError => ex
78
60
  end
79
- if ZuoraConnect.configuration.json_logging
80
- require 'json'
81
- store = {
82
- name: name,
83
- level: serverity,
84
- timestamp: datetime.strftime('%FT%T.%6NZ'),
85
- pid: Process.pid,
86
- message: name == "ActionMailer" ? msg.strip : msg
87
- }
88
- if !['ElasticAPM', 'ResqueScheduler', 'ResquePool','Resque', 'Makara'].include?(name)
89
- if Thread.current[:appinstance].present?
90
- store[:app_instance_id] = Thread.current[:appinstance].id
91
- logitems = Thread.current[:appinstance].logitems
92
- if logitems.present? && logitems.class == Hash
93
- store[:tenant_ids] = logitems[:tenant_ids] if logitems[:tenant_ids].present?
94
- store[:organization] = logitems[:organization] if logitems[:organization].present?
95
- end
61
+
62
+ require 'json'
63
+ store = {
64
+ name: name,
65
+ level: serverity,
66
+ timestamp: datetime.strftime('%FT%T.%6NZ'),
67
+ pid: Process.pid,
68
+ message: name == "ActionMailer" ? msg.strip : msg
69
+ }
70
+ if !['ElasticAPM', 'ResqueScheduler', 'ResquePool','Resque', 'Makara'].include?(name)
71
+ if Thread.current[:appinstance].present?
72
+ store[:app_instance_id] = Thread.current[:appinstance].id
73
+ logitems = Thread.current[:appinstance].logitems
74
+ if logitems.present? && logitems.class == Hash
75
+ store[:tenant_ids] = logitems[:tenant_ids] if logitems[:tenant_ids].present?
76
+ store[:organization] = logitems[:organization] if logitems[:organization].present?
96
77
  end
97
78
  end
98
- JSON.dump(store) + "\n"
99
- else
100
- format('%s %s: %s', serverity.ljust(6), datetime, msg) + "\n"
101
79
  end
80
+ JSON.dump(store) + "\n"
102
81
  end
103
82
  end
104
83
  return logger
105
- end
84
+ end
106
85
  end
107
86
 
108
87
  module Controllers
109
88
  autoload :Helpers, 'zuora_connect/controllers/helpers'
110
89
  end
111
90
 
91
+ module Views
92
+ ActionView::Base.send(:include, Helpers)
93
+ end
94
+
112
95
  def self.configuration
113
96
  @configuration ||= Configuration.new
114
97
  end
@@ -146,23 +129,23 @@ module ZuoraConnect
146
129
  }
147
130
  when 'test'
148
131
  defaults = {
149
- active: false,
132
+ active: false,
150
133
  disable_send: true
151
134
  }
152
135
  end
153
136
 
154
137
  defaults.merge!({
155
138
  disable_start_message: true,
156
- pool_size: 1,
157
- transaction_max_spans: 500,
158
- ignore_url_patterns: ['^\/admin\/resque.*', '^\/admin\/redis.*', '^\/admin\/peek.*', '^\/peek.*'],
139
+ pool_size: 1,
140
+ transaction_max_spans: 500,
141
+ ignore_url_patterns: ['^\/admin\/resque.*', '^\/admin\/redis.*', '^\/admin\/peek.*', '^\/peek.*'],
159
142
  verify_server_cert: false,
160
143
  log_level: Logger::INFO,
161
144
  service_name: ENV['DEIS_APP'].present? ? ENV['DEIS_APP'] : Rails.application.class.parent_name,
162
145
  logger: ZuoraConnect.custom_logger(name: "ElasticAPM", level: MonoLogger::WARN)
163
146
  })
164
147
  defaults.merge!({disable_send: true}) if defined?(Rails::Console)
165
-
148
+
166
149
  return defaults
167
150
  end
168
151
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5zz
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Connect Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-05 00:00:00.000000000 Z
11
+ date: 2019-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: apartment
@@ -39,59 +39,59 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: ougai-formatters-customizable
42
+ name: zuora_api
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 1.6.43
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: 1.6.43
48
51
  type: :runtime
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
55
  - - ">="
53
56
  - !ruby/object:Gem::Version
54
- version: '0'
57
+ version: 1.6.43
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 1.6.43
55
61
  - !ruby/object:Gem::Dependency
56
- name: zuora_api
62
+ name: httparty
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - ">="
60
66
  - !ruby/object:Gem::Version
61
- version: 1.6.48
67
+ version: 0.16.4
62
68
  - - "~>"
63
69
  - !ruby/object:Gem::Version
64
- version: 1.6.48
70
+ version: 0.16.4
65
71
  type: :runtime
66
72
  prerelease: false
67
73
  version_requirements: !ruby/object:Gem::Requirement
68
74
  requirements:
69
75
  - - ">="
70
76
  - !ruby/object:Gem::Version
71
- version: 1.6.48
77
+ version: 0.16.4
72
78
  - - "~>"
73
79
  - !ruby/object:Gem::Version
74
- version: 1.6.48
80
+ version: 0.16.4
75
81
  - !ruby/object:Gem::Dependency
76
- name: httparty
82
+ name: bundler
77
83
  requirement: !ruby/object:Gem::Requirement
78
84
  requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: 0.16.4
82
85
  - - "~>"
83
86
  - !ruby/object:Gem::Version
84
- version: 0.16.4
87
+ version: '1.12'
85
88
  type: :runtime
86
89
  prerelease: false
87
90
  version_requirements: !ruby/object:Gem::Requirement
88
91
  requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- version: 0.16.4
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: 0.16.4
94
+ version: '1.12'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: lograge
97
97
  requirement: !ruby/object:Gem::Requirement
@@ -308,13 +308,14 @@ files:
308
308
  - app/models/zuora_connect/zuora_user.rb
309
309
  - app/views/layouts/zuora_connect/application.html.erb
310
310
  - app/views/sql/refresh_aggregate_table.txt
311
- - app/views/zuora_connect/static/error_handled.html.erb
312
- - app/views/zuora_connect/static/error_unhandled.erb
311
+ - app/views/zuora_connect/static/invalid_app_instance_error.html.erb
312
+ - app/views/zuora_connect/static/invalid_launch_request.html.erb
313
313
  - app/views/zuora_connect/static/launch.html.erb
314
+ - app/views/zuora_connect/static/permission_error.html.erb
315
+ - app/views/zuora_connect/static/session_error.html.erb
314
316
  - config/initializers/apartment.rb
315
317
  - config/initializers/aws.rb
316
318
  - config/initializers/object_method_hooks.rb
317
- - config/initializers/patches.rb
318
319
  - config/initializers/postgresql_adapter.rb
319
320
  - config/initializers/prometheus.rb
320
321
  - config/initializers/redis.rb
@@ -334,11 +335,9 @@ files:
334
335
  - db/migrate/20180301052853_add_catalog_attempted_at.rb
335
336
  - db/migrate/20181206162339_add_fields_to_instance.rb
336
337
  - db/migrate/20190520232221_add_zuora_user_table_and_alter_app_instance_id_table.rb
337
- - db/migrate/20190520232222_add_unique_index.rb
338
338
  - lib/logging/connect_formatter.rb
339
339
  - lib/metrics/influx/point_value.rb
340
340
  - lib/metrics/net.rb
341
- - lib/middleware/json_parse_errors.rb
342
341
  - lib/middleware/metrics_middleware.rb
343
342
  - lib/middleware/request_id_middleware.rb
344
343
  - lib/resque/additions.rb
@@ -354,6 +353,7 @@ files:
354
353
  - lib/zuora_connect/exceptions.rb
355
354
  - lib/zuora_connect/railtie.rb
356
355
  - lib/zuora_connect/version.rb
356
+ - lib/zuora_connect/views/helpers.rb
357
357
  - test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb
358
358
  - test/dummy/README.rdoc
359
359
  - test/dummy/Rakefile
@@ -409,53 +409,53 @@ required_ruby_version: !ruby/object:Gem::Requirement
409
409
  version: '0'
410
410
  required_rubygems_version: !ruby/object:Gem::Requirement
411
411
  requirements:
412
- - - ">"
412
+ - - ">="
413
413
  - !ruby/object:Gem::Version
414
- version: 1.3.1
414
+ version: '0'
415
415
  requirements: []
416
416
  rubygems_version: 3.0.3
417
417
  signing_key:
418
418
  specification_version: 4
419
419
  summary: Summary of Connect.
420
420
  test_files:
421
+ - test/lib/generators/zuora_connect/datatable_generator_test.rb
421
422
  - test/integration/navigation_test.rb
422
- - test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb
423
+ - test/test_helper.rb
424
+ - test/models/zuora_connect/app_instance_test.rb
423
425
  - test/fixtures/zuora_connect/app_instances.yml
424
- - test/dummy/app/controllers/application_controller.rb
425
- - test/dummy/app/views/layouts/application.html.erb
426
+ - test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb
427
+ - test/zuora_connect_test.rb
428
+ - test/dummy/README.rdoc
429
+ - test/dummy/Rakefile
426
430
  - test/dummy/app/assets/stylesheets/application.css
427
431
  - test/dummy/app/assets/javascripts/application.js
432
+ - test/dummy/app/controllers/application_controller.rb
428
433
  - test/dummy/app/helpers/application_helper.rb
429
- - test/dummy/bin/setup
430
- - test/dummy/bin/bundle
431
- - test/dummy/bin/rake
432
- - test/dummy/bin/rails
433
- - test/dummy/config/routes.rb
434
- - test/dummy/config/environment.rb
435
- - test/dummy/config/application.rb
436
- - test/dummy/config/boot.rb
437
- - test/dummy/config/database.yml
434
+ - test/dummy/app/views/layouts/application.html.erb
435
+ - test/dummy/config/environments/test.rb
438
436
  - test/dummy/config/environments/production.rb
439
437
  - test/dummy/config/environments/development.rb
440
- - test/dummy/config/environments/test.rb
441
- - test/dummy/config/secrets.yml
442
- - test/dummy/config/locales/en.yml
443
- - test/dummy/config/initializers/inflections.rb
444
- - test/dummy/config/initializers/backtrace_silencers.rb
445
- - test/dummy/config/initializers/mime_types.rb
446
- - test/dummy/config/initializers/filter_parameter_logging.rb
438
+ - test/dummy/config/database.yml
439
+ - test/dummy/config/routes.rb
447
440
  - test/dummy/config/initializers/assets.rb
448
441
  - test/dummy/config/initializers/cookies_serializer.rb
442
+ - test/dummy/config/initializers/mime_types.rb
443
+ - test/dummy/config/initializers/backtrace_silencers.rb
444
+ - test/dummy/config/initializers/filter_parameter_logging.rb
449
445
  - test/dummy/config/initializers/session_store.rb
450
446
  - test/dummy/config/initializers/wrap_parameters.rb
451
- - test/dummy/public/favicon.ico
447
+ - test/dummy/config/initializers/inflections.rb
448
+ - test/dummy/config/locales/en.yml
449
+ - test/dummy/config/environment.rb
450
+ - test/dummy/config/application.rb
451
+ - test/dummy/config/boot.rb
452
+ - test/dummy/config/secrets.yml
453
+ - test/dummy/bin/setup
454
+ - test/dummy/bin/rails
455
+ - test/dummy/bin/bundle
456
+ - test/dummy/bin/rake
457
+ - test/dummy/config.ru
458
+ - test/dummy/public/422.html
452
459
  - test/dummy/public/500.html
460
+ - test/dummy/public/favicon.ico
453
461
  - test/dummy/public/404.html
454
- - test/dummy/public/422.html
455
- - test/dummy/Rakefile
456
- - test/dummy/README.rdoc
457
- - test/dummy/config.ru
458
- - test/lib/generators/zuora_connect/datatable_generator_test.rb
459
- - test/test_helper.rb
460
- - test/zuora_connect_test.rb
461
- - test/models/zuora_connect/app_instance_test.rb
@@ -1,77 +0,0 @@
1
- <html>
2
- <head>
3
- <title>Handled Error</title>
4
- <meta name="viewport" content="width=device-width,initial-scale=1">
5
- <style>
6
- body {
7
- background-color: white;
8
- color: #2E2F30;
9
- text-align: center;
10
- font-family: arial, sans-serif;
11
- margin: 0;
12
- }
13
-
14
- div.dialog {
15
- width: 95%;
16
- max-width: 33em;
17
- margin: 4em auto 0;
18
- }
19
-
20
- div.dialog > div {
21
- border: 1px solid #CCC;
22
- border-right-color: #999;
23
- border-left-color: #999;
24
- border-bottom-color: #BBB;
25
- border-top: #3D4B5A solid 4px;
26
- border-top-left-radius: 9px;
27
- border-top-right-radius: 9px;
28
- background-color: white;
29
- padding: 7px 12% 0;
30
- box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
31
- }
32
-
33
- h1 {
34
- font-size: 100%;
35
- color: #3D4B5A;
36
- line-height: 1.5em;
37
- }
38
- div.dialog > p {
39
- margin: 0 0 1em;
40
- padding: 1em;
41
- background-color: #F7F7F7;
42
- border: 1px solid #CCC;
43
- border-right-color: #999;
44
- border-left-color: #999;
45
- border-bottom-color: #999;
46
- border-bottom-left-radius: 4px;
47
- border-bottom-right-radius: 4px;
48
- border-top-color: #DADADA;
49
- color: #666;
50
- box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
51
- }
52
- </style>
53
- </head>
54
-
55
- <body>
56
- <% if defined?(exception) %>
57
- <div class="dialog" style='max-width: 74em;'>
58
- <div><h1><%= exception.class %> - '<%= exception.message %>'</h1></div>
59
- <p style='text-align: left;'>
60
- <% exception.backtrace.each do |line| %>
61
- <%= line %><br>
62
- <% end %>
63
- </p>
64
- </div>
65
- <% elsif defined?(message) && defined?(title) %>
66
- <div class="dialog">
67
- <div><h1><%= title %></h1></div>
68
- <p><%= message.html_safe %></p>
69
- </div>
70
- <% else %>
71
- <div class="dialog">
72
- <div><h1>The launch url was invalid</h1></div>
73
- <p>Please try relaunching this application</p>
74
- </div>
75
- <% end %>
76
- </body>
77
- </html>
@@ -1,76 +0,0 @@
1
- <html>
2
- <head>
3
- <title>We're sorry, but something went wrong</title>
4
- <meta name="viewport" content="width=device-width,initial-scale=1">
5
- <style>
6
- body {
7
- background-color: #EFEFEF;
8
- color: #2E2F30;
9
- text-align: center;
10
- font-family: arial, sans-serif;
11
- margin: 0;
12
- }
13
-
14
- div.dialog {
15
- width: 95%;
16
- max-width: 33em;
17
- margin: 4em auto 0;
18
- }
19
-
20
- div.dialog > div {
21
- border: 1px solid #CCC;
22
- border-right-color: #999;
23
- border-left-color: #999;
24
- border-bottom-color: #BBB;
25
- border-top: #B00100 solid 4px;
26
- border-top-left-radius: 9px;
27
- border-top-right-radius: 9px;
28
- background-color: white;
29
- padding: 7px 12% 0;
30
- box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
31
- }
32
-
33
- h1 {
34
- font-size: 100%;
35
- color: #730E15;
36
- line-height: 1.5em;
37
- }
38
-
39
- div.dialog > p {
40
- margin: 0 0 1em;
41
- padding: 1em;
42
- background-color: #F7F7F7;
43
- border: 1px solid #CCC;
44
- border-right-color: #999;
45
- border-left-color: #999;
46
- border-bottom-color: #999;
47
- border-bottom-left-radius: 4px;
48
- border-bottom-right-radius: 4px;
49
- border-top-color: #DADADA;
50
- color: #666;
51
- box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
52
- }
53
- </style>
54
- </head>
55
-
56
- <body>
57
- <!-- This file lives in public/500.html -->
58
- <% if defined?(exception) %>
59
- <div class="dialog" style='max-width: 74em;'>
60
- <div><h1><%= exception.class %> - '<%= exception.message %>'</h1></div>
61
- <p style='text-align: left;'>
62
- <% exception.backtrace.each do |line| %>
63
- <%= line %><br>
64
- <% end %>
65
- </p>
66
- </div>
67
- <% else %>
68
- <div class="dialog">
69
- <div>
70
- <h1>The launch url was invalid</h1>
71
- </div>
72
- <p>Please try relaunching this application</p>
73
- </div>
74
- <% end %>
75
- </body>
76
- </html>
@@ -1,9 +0,0 @@
1
- #Used to ensure encode of UploadedFile for lograge does not dump entire file.
2
- class ActionDispatch::Http::UploadedFile
3
- def as_json(options = nil)
4
- %w(headers).inject({}) do |hash, attr|
5
- hash[attr] = send(attr).force_encoding('utf-8')
6
- hash
7
- end
8
- end
9
- end
@@ -1,6 +0,0 @@
1
- class AddUniqueIndex < ActiveRecord::Migration[5.0]
2
- def change
3
- add_index :zuora_connect_app_instances, :api_token, unique: true unless ActiveRecord::Base.connection.index_exists?(:zuora_connect_app_instances, :api_token, unique: true)
4
- add_index :zuora_connect_app_instances, :token, unique: true unless ActiveRecord::Base.connection.index_exists?(:zuora_connect_app_instances, :token, unique: true)
5
- end
6
- end
@@ -1,22 +0,0 @@
1
- module ZuoraConnect
2
- class JsonParseErrors
3
- def initialize(app)
4
- @app = app
5
- end
6
-
7
- def call(env)
8
- begin
9
- @app.call(env)
10
- rescue ActionDispatch::ParamsParser::ParseError => error
11
- if env['HTTP_ACCEPT'] =~ /application\/json/ || env['CONTENT_TYPE'] =~ /application\/json/
12
- return [
13
- 400, { "Content-Type" => "application/json" },
14
- [{"success": false, "reasons": [{"code": 50000090, "message": "Malformed json was submitted." }]}.to_json ]
15
- ]
16
- else
17
- raise error
18
- end
19
- end
20
- end
21
- end
22
- end