usps-imis-api 0.11.23 → 1.0.0.pre.rc.1

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +57 -0
  3. data/.gitignore +4 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +88 -0
  6. data/.ruby-version +1 -0
  7. data/.simplecov +8 -0
  8. data/Gemfile +12 -0
  9. data/Gemfile.lock +95 -0
  10. data/Rakefile +12 -0
  11. data/Readme.md +191 -19
  12. data/bin/console +21 -0
  13. data/bin/setup +8 -0
  14. data/lib/ext/hash.rb +10 -0
  15. data/lib/usps/imis/api.rb +138 -177
  16. data/lib/usps/imis/config.rb +10 -68
  17. data/lib/usps/imis/error/api.rb +26 -0
  18. data/lib/usps/imis/error/mapper.rb +9 -0
  19. data/lib/usps/imis/{errors/response_error.rb → error/response.rb} +7 -34
  20. data/lib/usps/imis/mapper.rb +21 -90
  21. data/lib/usps/imis/panel/base_panel.rb +42 -0
  22. data/lib/usps/imis/panel/education.rb +111 -0
  23. data/lib/usps/imis/panel/vsc.rb +109 -0
  24. data/lib/usps/imis/version.rb +1 -1
  25. data/lib/usps/imis.rb +17 -32
  26. data/spec/lib/usps/imis/api_spec.rb +143 -0
  27. data/spec/lib/usps/imis/config_spec.rb +33 -0
  28. data/spec/lib/usps/imis/error/api_spec.rb +17 -0
  29. data/spec/lib/usps/imis/error/response_spec.rb +107 -0
  30. data/spec/lib/usps/imis/mapper_spec.rb +31 -0
  31. data/spec/lib/usps/imis/panel/base_panel_spec.rb +32 -0
  32. data/spec/lib/usps/imis/panel/education_spec.rb +55 -0
  33. data/spec/lib/usps/imis/panel/vsc_spec.rb +38 -0
  34. data/spec/lib/usps/imis_spec.rb +11 -0
  35. data/spec/spec_helper.rb +35 -0
  36. data/usps-imis-api.gemspec +18 -0
  37. metadata +33 -94
  38. data/bin/imis +0 -8
  39. data/lib/usps/imis/business_object.rb +0 -209
  40. data/lib/usps/imis/command_line/interface.rb +0 -204
  41. data/lib/usps/imis/command_line/options_parser.rb +0 -136
  42. data/lib/usps/imis/command_line.rb +0 -15
  43. data/lib/usps/imis/data.rb +0 -76
  44. data/lib/usps/imis/error.rb +0 -55
  45. data/lib/usps/imis/errors/api_error.rb +0 -11
  46. data/lib/usps/imis/errors/command_line_error.rb +0 -11
  47. data/lib/usps/imis/errors/config_error.rb +0 -11
  48. data/lib/usps/imis/errors/locked_id_error.rb +0 -15
  49. data/lib/usps/imis/errors/mapper_error.rb +0 -29
  50. data/lib/usps/imis/errors/missing_id_error.rb +0 -15
  51. data/lib/usps/imis/errors/not_found_error.rb +0 -11
  52. data/lib/usps/imis/errors/panel_unimplemented_error.rb +0 -34
  53. data/lib/usps/imis/errors/unexpected_property_type_error.rb +0 -31
  54. data/lib/usps/imis/logger.rb +0 -19
  55. data/lib/usps/imis/logger_formatter.rb +0 -32
  56. data/lib/usps/imis/logger_helpers.rb +0 -17
  57. data/lib/usps/imis/mocks/business_object.rb +0 -47
  58. data/lib/usps/imis/mocks.rb +0 -11
  59. data/lib/usps/imis/panels/base_panel.rb +0 -158
  60. data/lib/usps/imis/panels/education.rb +0 -33
  61. data/lib/usps/imis/panels/vsc.rb +0 -32
  62. data/lib/usps/imis/panels.rb +0 -25
  63. data/lib/usps/imis/properties.rb +0 -50
  64. data/lib/usps/imis/query.rb +0 -153
  65. data/lib/usps/imis/requests.rb +0 -68
  66. data/spec/support/usps/vcr/config.rb +0 -47
  67. data/spec/support/usps/vcr/filters.rb +0 -89
  68. data/spec/support/usps/vcr.rb +0 -8
@@ -1,209 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'requests'
4
- require_relative 'data'
5
-
6
- module Usps
7
- module Imis
8
- # DEV
9
- class BusinessObject
10
- include Requests
11
-
12
- # Endpoint for general API requests
13
- #
14
- API_PATH = 'api'
15
-
16
- # The parent +Api+ object
17
- #
18
- attr_reader :api
19
-
20
- # Name of the iMIS Business Object
21
- #
22
- attr_reader :business_object_name
23
-
24
- # Ordinal to build override ID param of the URL (e.g. used for Panels)
25
- #
26
- attr_reader :ordinal
27
-
28
- # Tagged logger
29
- #
30
- attr_reader :logger
31
-
32
- # A new instance of +BusinessObject+
33
- #
34
- def initialize(api, business_object_name, ordinal: nil)
35
- @api = api
36
- @business_object_name = business_object_name
37
- @ordinal = ordinal
38
- @logger ||= Imis.logger('BusinessObject')
39
- end
40
-
41
- # Run a query on the entire business object
42
- #
43
- # @return [Usps::Imis::Query] Query wrapper
44
- #
45
- def query = api.query(business_object_name)
46
-
47
- # Support passthrough for Api#with
48
- #
49
- def with(imis_id, &)
50
- # Bring into local scope
51
- wrapper_business_object_name = business_object_name
52
- wrapper_ordinal = ordinal
53
-
54
- api.with(imis_id) do
55
- on(wrapper_business_object_name, ordinal: wrapper_ordinal, &)
56
- end
57
- end
58
-
59
- # Get a business object for the current member
60
- #
61
- # If +fields+ is provided, will return only those field values
62
- #
63
- # @param fields [String] Field names to return
64
- #
65
- # @return [Usps::Imis::Data, Array<Usps::Imis::Data>] Response data from the API
66
- #
67
- def get(*fields) = fields.any? ? get_fields(*fields) : raw_object
68
- alias read get
69
-
70
- # Get a single named field from a business object for the current member
71
- #
72
- # @param field [String] Field name to return
73
- #
74
- # @return Response data field value from the API
75
- #
76
- def get_field(field) = raw_object[field]
77
- alias fetch get_field
78
- alias [] get_field
79
-
80
- # Get named fields from a business object for the current member
81
- #
82
- # @param names [Array<String>] Field names to return
83
- #
84
- # @return [Array] Response data from the API
85
- #
86
- def get_fields(*fields)
87
- values = raw_object
88
- fields.map { values[it] }
89
- end
90
- alias fetch_all get_fields
91
-
92
- # Update a single named field on a business object for the current member
93
- #
94
- # @param field [String] Name of the field
95
- # @param value Value of the field
96
- #
97
- # @return [Usps::Imis::Data] Response data from the API
98
- #
99
- def put_field(field, value) = put(filter_fields(field => value))
100
- alias []= put_field
101
-
102
- # Update only specific fields on a business object for the current member
103
- #
104
- # @param fields [Hash] Conforms to pattern +{ field_key => value }+
105
- #
106
- # @return [Usps::Imis::Data] Response data from the API
107
- #
108
- def put_fields(fields) = put(filter_fields(fields))
109
- alias patch put_fields
110
-
111
- # Update a business object for the current member
112
- #
113
- # Any properties not included will be left unmodified
114
- #
115
- # @param body [Hash] Full raw API object data
116
- #
117
- # @return [Usps::Imis::Data] Response data from the API
118
- #
119
- def put(body) = put_object(http_put, body)
120
- alias update put
121
-
122
- # Create a business object for the current member
123
- #
124
- # @param body [Hash] Full raw API object data
125
- #
126
- # @return [Usps::Imis::Data] Response data from the API
127
- #
128
- def post(body) = put_object(http_post, body)
129
- alias create post
130
-
131
- # Remove a business object for the current member
132
- #
133
- # @return [true] Only on success response (i.e. blank string from the API)
134
- #
135
- def delete = submit(uri, authorize(http_delete)).body == '' # rubocop:disable Naming/PredicateMethod
136
- alias destroy delete
137
-
138
- # Ruby 3.5 instance variable filter
139
- #
140
- def instance_variables_to_inspect = instance_variables - %i[@api @logger]
141
-
142
- private
143
-
144
- # Construct a business object API endpoint address
145
- #
146
- def uri(id: nil)
147
- full_path = "#{API_PATH}/#{business_object_name}/#{id_for_uri(id)}"
148
- URI(File.join(Imis.configuration.hostname, full_path))
149
- end
150
-
151
- # Select the correct ID to use in the URI
152
- #
153
- def id_for_uri(id = nil)
154
- return CGI.escape(id) unless id.nil?
155
- return CGI.escape("~#{api.imis_id}|#{ordinal}") if ordinal
156
-
157
- api.imis_id.to_s
158
- end
159
-
160
- # Manually assemble the matching data structure, with fields in the correct order
161
- #
162
- def filter_fields(fields)
163
- existing = get
164
-
165
- JSON.parse(JSON.dump(existing)).tap do |updated|
166
- # Preserve the iMIS ID, as well as the Ordinal (if present)
167
- updated['Properties']['$values'], properties =
168
- existing.raw['Properties']['$values'].partition { %w[ID Ordinal].include?(it['Name']) }
169
-
170
- # Iterate through all existing fields
171
- properties.each do |value|
172
- # Skip unmodified fields
173
- next unless fields.keys.include?(value['Name'])
174
-
175
- value['Value'] = Properties.wrap(fields[value['Name']])
176
-
177
- # Add the completed field with the updated value
178
- updated['Properties']['$values'] << value
179
- end
180
- end
181
- end
182
-
183
- # Get a raw object response from the API
184
- #
185
- # Useful for stubbing data in tests
186
- #
187
- def raw_object
188
- raise Errors::MissingIdError if api.imis_id.nil?
189
-
190
- response = submit(uri, authorize(http_get))
191
- result = Data.from_json(response.body)
192
- logger.json result
193
- result
194
- end
195
-
196
- # Upload an object to the API
197
- #
198
- def put_object(request, body)
199
- raise Errors::MissingIdError if api.imis_id.nil?
200
-
201
- request.body = JSON.dump(body)
202
- response = submit(uri, authorize(request))
203
- result = Data.from_json(response.body)
204
- logger.json result
205
- result
206
- end
207
- end
208
- end
209
- end
@@ -1,204 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Imis
5
- module CommandLine
6
- # Command line interface for the Api
7
- #
8
- class Interface
9
- NAME = 'USPS iMIS API - Ruby'
10
-
11
- # CLI options that indicate the response is a raw Hash rather than a Data object,
12
- # and should not be simplified
13
- #
14
- RAW_HASH_RESPONSE_OPTIONS = %i[business_objects auth_token].freeze
15
-
16
- # Options passed in from the command line
17
- #
18
- attr_reader :options
19
-
20
- # Tagged logger
21
- #
22
- attr_reader :logger
23
-
24
- def self.run(...) = new(...).run
25
-
26
- def initialize(**)
27
- @options = input_options.merge(**)
28
- options[:version] = true if default_options?
29
-
30
- configure! if options[:config]
31
- logging!
32
- @logger ||= Imis.logger('CommandLine')
33
- end
34
-
35
- def run
36
- logger.info 'Running'
37
- logger.debug 'CLI Options:'
38
- logger.json(options.dup.tap { it[:token] = '[FILTERED]' if it[:token] })
39
-
40
- set_member
41
-
42
- result = simplify(perform!)
43
-
44
- output { result }
45
-
46
- result
47
- end
48
-
49
- private
50
-
51
- # :nocov:
52
- def input_options
53
- if ENV.fetch('CI', false) || ENV.fetch('TESTING', false)
54
- defaults = {
55
- raw: false,
56
- quiet: false,
57
- log: false,
58
- log_level: 'info',
59
- version: false,
60
- help: false
61
- }
62
- return defaults
63
- end
64
-
65
- OptionsParser.new.options
66
- end
67
- # :nocov:
68
-
69
- def api
70
- @api ||=
71
- if options[:token]
72
- Usps::Imis::Api.with_token(options[:token])
73
- else
74
- Usps::Imis::Api.new
75
- end
76
- end
77
-
78
- def set_member
79
- case options
80
- in certificate: then api.imis_id_for(certificate)
81
- in id: then api.imis_id = id
82
- else
83
- # Query
84
- end
85
-
86
- logger.debug "iMIS ID: #{api.imis_id}" if api.imis_id
87
- end
88
-
89
- # rubocop:disable Metrics
90
- def perform!
91
- case convert(options)
92
- in mapper:, field:, data: then mapper.put_field(field.to_sym, data)
93
- in mapper:, fields: then mapper.get_fields(*fields)
94
- in mapper:, field: then mapper.get_field(field.to_sym)
95
- in mapper:, data: then mapper.update(data)
96
-
97
- in on:, delete: true then on.delete
98
- in on:, create: true, data: then on.post(data)
99
- in on:, data:, field: then on.put_field(field, data)
100
- in on:, data: then on.put_fields(data)
101
- in on:, fields: then on.get_fields(*fields)
102
- in on:, field: then on.get_field(field)
103
- in on: then on.get
104
-
105
- in panel:, delete: true, ordinal: then panel.delete(ordinal)
106
- in panel:, create: true, data: then panel.post(data)
107
- in panel:, ordinal:, data:, field: then panel.put_field(ordinal, field, data)
108
- in panel:, ordinal:, data: then panel.put_fields(ordinal, data)
109
- in panel:, ordinal:, fields: then panel.get_fields(ordinal, *fields)
110
- in panel:, ordinal:, field: then panel.get_field(ordinal, field)
111
- in panel:, ordinal: then panel.get(ordinal)
112
-
113
- in query:, data: then api.query(query, data)
114
- in query: then api.query(query)
115
-
116
- in business_objects: true then api.business_objects
117
-
118
- in auth_token: true then api.auth_token
119
-
120
- in certificate: then api.imis_id
121
-
122
- in version: true then "#{Interface::NAME} (v#{Imis::VERSION})"
123
- end
124
- rescue NoMatchingPatternError => e
125
- raise Errors::CommandLineError, "Unable to match pattern from options: #{e.message}"
126
- end
127
- # rubocop:enable Metrics
128
-
129
- def convert(options)
130
- options.dup.tap do |converted|
131
- case converted
132
- in map: then converted.merge!(mapper: api.mapper, field: map)
133
- in mapper: true then converted[:mapper] = api.mapper
134
- in on: then converted[:on] = api.on(on)
135
- in panel: then converted[:panel] = api.panels.public_send(panel)
136
- else
137
- # Nothing to convert
138
- end
139
-
140
- # Remove mapper flag when false
141
- converted.delete(:mapper) unless converted[:mapper]
142
- end
143
- end
144
-
145
- def simplify(data)
146
- return data.to_a if data.is_a?(Query)
147
- return data if options[:raw] || RAW_HASH_RESPONSE_OPTIONS.any? { options[it] }
148
-
149
- # Hash includes Usps::Imis::Data
150
- if data.is_a?(Hash)
151
- logger.debug 'Returning simplified Data#properties'
152
- data.properties(include_ids: options[:include_ids])
153
- elsif data.is_a?(Array) && data.all? { it.is_a?(Hash) }
154
- logger.debug 'Returning simplified Array<Data#properties>'
155
- data.map { it.properties(include_ids: options[:include_ids]) }
156
- else
157
- data
158
- end
159
- end
160
-
161
- # :nocov:
162
- def output(&block)
163
- if ENV.fetch('SUPPRESS_OUTPUT', false)
164
- logger.debug 'Output suppressed'
165
- return
166
- end
167
-
168
- puts JSON.dump(block.call) if block_given?
169
- end
170
- # :nocov:
171
-
172
- # Supports YAML or JSON config data
173
- #
174
- def configure!
175
- config_data = YAML.safe_load_file(options[:config])
176
-
177
- Usps::Imis.configure do |config|
178
- config_data.each do |key, value|
179
- config.public_send("#{key}=", value)
180
- end
181
- end
182
- end
183
-
184
- def logging!
185
- Usps::Imis.configure do |config|
186
- # :nocov:
187
- if options[:quiet] || ENV.fetch('SUPPRESS_OUTPUT', false)
188
- config.logger = ActiveSupport::TaggedLogging.new(Logger.new(nil))
189
- elsif options[:log] || config.logger_file
190
- # Use default, or configured file
191
- else
192
- config.logger = ActiveSupport::TaggedLogging.new(Logger.new($stderr))
193
- end
194
- # :nocov:
195
-
196
- config.logger.level = options[:log_level]
197
- end
198
- end
199
-
200
- def default_options? = options[:log_level] == 'info' && options.except(:log_level).values.none?
201
- end
202
- end
203
- end
204
- end
@@ -1,136 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Imis
5
- module CommandLine
6
- # Command line options parser
7
- #
8
- class OptionsParser
9
- OPTIONS = {
10
- # IDs
11
- certificate: ['Member certificate number', { type: :string }],
12
- id: ['Member iMIS ID', { type: :integer }],
13
-
14
- # Primary interactions
15
- on: ['Business Object name', { type: :string }],
16
- panel: ['Panel name', { type: :string }],
17
- query: ['IQA Query or Business Object name to query', { type: :string, short: :Q }],
18
- mapper: ['Interact with mapped fields', { short: :M }],
19
- map: ["Shorthand for #{'-Mf'.green} to access a single mapped field", { type: :string }],
20
- business_objects: ['List available Business Objects'],
21
-
22
- # Alternate verbs
23
- create: ["Send a #{'POST'.cyan} request", { short: :P }],
24
- delete: ["Send a #{'DELETE'.cyan} request", { short: :D }],
25
-
26
- # Data
27
- ordinal: ['Ordinal ID within a Panel', { type: :integer }],
28
- field: ['Specific field to return or update', { type: :string }],
29
- fields: ['Specific field(s) to return', { type: :strings, short: :F }],
30
- data: ['JSON string input', { type: :string }],
31
-
32
- # Iteractions for supporting other language wrappers
33
- auth_token: ['Return an auth token for other language wrappers', { short: :T }],
34
- token: ['Provide an existing auth token', { type: :string }],
35
-
36
- # General config
37
- config: ['Path to the JSON/YAML config file to use', { type: :string, short: :C }],
38
- raw: ['Return raw JSON output, rather than simplified data', { short: :R }],
39
- include_ids: ["Include any #{'iMIS ID'.yellow} and #{'Ordinal'.yellow} properties in returned data"],
40
- quiet: ["Suppress logging to #{'STDERR'.red}"],
41
- log: ["Redirect logging to #{'STDOUT'.red}"],
42
- log_level: ['Set the logging level', { type: :string, default: 'info', short: :L }]
43
- }.freeze
44
-
45
- CONFLICTING_OPTION_GROUPS = [
46
- %i[certificate id],
47
- %i[on panel query mapper map business_objects auth_token],
48
- %i[field fields map query],
49
- %i[raw include_ids],
50
- %i[quiet log_level],
51
- %i[quiet log],
52
-
53
- %i[create delete],
54
-
55
- %i[create mapper],
56
- %i[create query],
57
- %i[create map],
58
- %i[create field],
59
- %i[create fields],
60
-
61
- %i[delete mapper],
62
- %i[delete query],
63
- %i[delete map],
64
- %i[delete field],
65
- %i[delete fields],
66
- %i[delete data],
67
- %i[delete raw]
68
- ].freeze
69
-
70
- attr_reader :arguments, :options
71
-
72
- def self.banner_header(version)
73
- <<~BANNER
74
- #{version.bold.blue}
75
- #{'P/R/C Julian Fiander, SN'.gray}\n \n
76
- BANNER
77
- end
78
-
79
- def self.banner_contents
80
- <<~BANNER
81
- #{'Usage'.underline}
82
-
83
- #{'imis'.bold} #{'[options]'.gray}
84
-
85
-
86
- #{'Further Help'.underline}
87
-
88
- For an explanation of how to provide API configuration, more details on the options,
89
- and usage examples, please refer to the wiki:
90
-
91
- https://github.com/unitedstatespowersquadrons/imis-api-ruby/wiki/Command-Line
92
-
93
-
94
- #{'Options'.underline}
95
- BANNER
96
- end
97
-
98
- def initialize
99
- @options = parse_options.compact
100
- @arguments = ARGV # Not currently used
101
-
102
- Optimist.educate if ARGV.empty? && defaults? # DEV: This shadows setting the --version flag by default
103
-
104
- # :nocov:
105
- @options[:data] = read_stdin if stdin?
106
- # :nocov:
107
-
108
- @options[:data] = JSON.parse(@options[:data]) if @options[:data]
109
- end
110
-
111
- private
112
-
113
- def parse_options
114
- Optimist.options do
115
- version "#{Interface::NAME} (v#{Usps::Imis::VERSION})"
116
-
117
- banner OptionsParser.banner_header(version)
118
- banner OptionsParser.banner_contents
119
-
120
- OPTIONS.each { |option, data| opt(option, *data) }
121
- CONFLICTING_OPTION_GROUPS.each { |group| conflicts(*group) }
122
-
123
- educate_on_error
124
- end
125
- end
126
-
127
- # :nocov:
128
- def stdin? = $stdin.wait_readable(0)
129
- def read_stdin = $stdin.read.chomp
130
- # :nocov:
131
-
132
- def defaults? = options[:log_level] == 'info' && options.except(:log_level).values.none?
133
- end
134
- end
135
- end
136
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'optimist'
4
- require 'colorize'
5
-
6
- module Usps
7
- module Imis
8
- # Wrapper for the command line interface
9
- #
10
- module CommandLine; end
11
- end
12
- end
13
-
14
- require_relative 'command_line/options_parser'
15
- require_relative 'command_line/interface'
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'pp'
4
- require 'stringio'
5
-
6
- module Usps
7
- module Imis
8
- # Convenience wrapper for accessing specific properties within an API data response
9
- #
10
- class Data < Hash
11
- # Load raw API response JSON to access properties
12
- #
13
- # @param json [String] Raw API response JSON
14
- #
15
- def self.from_json(json) = self[JSON.parse(json)]
16
-
17
- alias raw to_h
18
-
19
- # The Business Object or Panel name
20
- #
21
- def entity = raw['EntityTypeName']
22
-
23
- # Access the iMIS ID property
24
- #
25
- def imis_id = self['ID'].to_i
26
- alias id imis_id
27
-
28
- # Access the Ordinal identifier property (if present)
29
- #
30
- def ordinal = self['Ordinal']&.to_i
31
-
32
- # Access an individual property value by name
33
- #
34
- def [](property_name)
35
- property = raw['Properties']['$values'].find { it['Name'] == property_name }
36
- return if property.nil?
37
-
38
- value = property['Value']
39
- value.nil? || value.is_a?(String) ? value : value['$value']
40
- end
41
-
42
- # Hash of all property names to values
43
- #
44
- # @param include_ids [Boolean] Whether to include the iMIS ID and Ordinal
45
- #
46
- def properties(include_ids: false)
47
- raw['Properties']['$values']
48
- .map { it['Name'] }
49
- .select { include_ids || !%w[ID Ordinal].include?(it) }
50
- .index_with { self[it] }
51
- end
52
-
53
- def []=(...)
54
- raise Errors::ApiError, '`Data` does not support setting values. If you need to modify it, call `.raw` on it.'
55
- end
56
-
57
- def inspect
58
- stringio = StringIO.new
59
- PP.pp(self, stringio)
60
- stringio.string.delete("\n")
61
- end
62
-
63
- def pretty_print(pp)
64
- data = { entity:, imis_id:, ordinal: }.compact
65
-
66
- pp.group(1, "#<#{self.class}", '>') do
67
- data.each do |key, value|
68
- pp.breakable
69
- pp.text "#{key}="
70
- pp.pp value
71
- end
72
- end
73
- end
74
- end
75
- end
76
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Imis
5
- # Base error class for all internal exceptions
6
- #
7
- class Error < StandardError
8
- # Additional call-specific metadata to pass through to Bugsnag
9
- #
10
- attr_accessor :metadata
11
-
12
- # A new instance of +ApiError+
13
- #
14
- # @param message [String] The base exception message
15
- # @param metadata [Hash] Additional call-specific metadata to pass through to Bugsnag
16
- #
17
- def initialize(message, metadata = {})
18
- super(message)
19
- @metadata = metadata
20
-
21
- Imis.logger(self.class.name).error self
22
- end
23
-
24
- # Additional metadata to include in Bugsnag reports
25
- #
26
- # Can include fields at the top level, which will be shows on the custom tab
27
- #
28
- # Can include fields nested under a top-level key, which will be shown on a tab with the
29
- # top-level key as its name
30
- #
31
- # @return [Hash]
32
- #
33
- def bugsnag_meta_data
34
- metadata == {} ? {} : base_metadata
35
- end
36
-
37
- private
38
-
39
- def base_metadata
40
- { api: metadata }
41
- end
42
- end
43
- end
44
- end
45
-
46
- require_relative 'errors/api_error'
47
- require_relative 'errors/config_error'
48
- require_relative 'errors/locked_id_error'
49
- require_relative 'errors/mapper_error'
50
- require_relative 'errors/missing_id_error'
51
- require_relative 'errors/not_found_error'
52
- require_relative 'errors/response_error'
53
- require_relative 'errors/panel_unimplemented_error'
54
- require_relative 'errors/unexpected_property_type_error'
55
- require_relative 'errors/command_line_error'
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Imis
5
- module Errors
6
- # Generic exception raised from within the gem
7
- #
8
- class ApiError < Error; end
9
- end
10
- end
11
- end