easypost 3.5.1 → 5.2.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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +9 -0
  3. data/.github/CODEOWNERS +2 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.yml +81 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.yml +37 -0
  6. data/.github/PULL_REQUEST_TEMPLATE.md +22 -0
  7. data/.github/workflows/ci.yml +54 -5
  8. data/.gitignore +27 -17
  9. data/.gitmodules +3 -0
  10. data/CHANGELOG.md +295 -119
  11. data/Gemfile +2 -0
  12. data/Makefile +70 -0
  13. data/README.md +184 -72
  14. data/Rakefile +2 -1
  15. data/UPGRADE_GUIDE.md +181 -0
  16. data/VERSION +1 -1
  17. data/bin/easypost-irb +5 -3
  18. data/easypost.gemspec +27 -20
  19. data/lib/easypost/client.rb +179 -0
  20. data/lib/easypost/connection.rb +64 -0
  21. data/lib/easypost/constants.rb +15 -0
  22. data/lib/easypost/errors/api/api_error.rb +108 -0
  23. data/lib/easypost/errors/api/bad_request_error.rb +6 -0
  24. data/lib/easypost/errors/api/connection_error.rb +6 -0
  25. data/lib/easypost/errors/api/external_api_error.rb +18 -0
  26. data/lib/easypost/errors/api/forbidden_error.rb +6 -0
  27. data/lib/easypost/errors/api/gateway_timeout_error.rb +6 -0
  28. data/lib/easypost/errors/api/internal_server_error.rb +6 -0
  29. data/lib/easypost/errors/api/invalid_request_error.rb +6 -0
  30. data/lib/easypost/errors/api/method_not_allowed_error.rb +6 -0
  31. data/lib/easypost/errors/api/not_found_error.rb +6 -0
  32. data/lib/easypost/errors/api/payment_error.rb +6 -0
  33. data/lib/easypost/errors/api/proxy_error.rb +6 -0
  34. data/lib/easypost/errors/api/rate_limit_error.rb +6 -0
  35. data/lib/easypost/errors/api/redirect_error.rb +6 -0
  36. data/lib/easypost/errors/api/retry_error.rb +6 -0
  37. data/lib/easypost/errors/api/service_unavailable_error.rb +6 -0
  38. data/lib/easypost/errors/api/ssl_error.rb +6 -0
  39. data/lib/easypost/errors/api/timeout_error.rb +6 -0
  40. data/lib/easypost/errors/api/unauthorized_error.rb +6 -0
  41. data/lib/easypost/errors/api/unknown_api_error.rb +6 -0
  42. data/lib/easypost/errors/easy_post_error.rb +7 -0
  43. data/lib/easypost/errors/end_of_pagination_error.rb +7 -0
  44. data/lib/easypost/errors/filtering_error.rb +4 -0
  45. data/lib/easypost/errors/invalid_object_error.rb +4 -0
  46. data/lib/easypost/errors/invalid_parameter_error.rb +11 -0
  47. data/lib/easypost/errors/missing_parameter_error.rb +9 -0
  48. data/lib/easypost/errors/signature_verification_error.rb +4 -0
  49. data/lib/easypost/errors.rb +32 -0
  50. data/lib/easypost/hooks/request_context.rb +16 -0
  51. data/lib/easypost/hooks/response_context.rb +23 -0
  52. data/lib/easypost/hooks.rb +34 -0
  53. data/lib/easypost/http_client.rb +117 -0
  54. data/lib/easypost/internal_utilities.rb +66 -0
  55. data/lib/easypost/models/address.rb +5 -0
  56. data/lib/easypost/models/api_key.rb +5 -0
  57. data/lib/easypost/models/base.rb +58 -0
  58. data/lib/easypost/models/batch.rb +5 -0
  59. data/lib/easypost/models/brand.rb +5 -0
  60. data/lib/easypost/models/carbon_offset.rb +5 -0
  61. data/lib/easypost/models/carrier_account.rb +5 -0
  62. data/lib/easypost/models/carrier_type.rb +5 -0
  63. data/lib/easypost/models/customs_info.rb +5 -0
  64. data/lib/easypost/models/customs_item.rb +5 -0
  65. data/lib/easypost/models/end_shipper.rb +5 -0
  66. data/lib/easypost/models/error.rb +21 -0
  67. data/lib/easypost/models/event.rb +5 -0
  68. data/lib/easypost/models/insurance.rb +6 -0
  69. data/lib/easypost/models/order.rb +9 -0
  70. data/lib/easypost/models/parcel.rb +5 -0
  71. data/lib/easypost/models/payload.rb +5 -0
  72. data/lib/easypost/models/payment_method.rb +5 -0
  73. data/lib/easypost/models/pickup.rb +9 -0
  74. data/lib/easypost/models/pickup_rate.rb +5 -0
  75. data/lib/easypost/models/postage_label.rb +5 -0
  76. data/lib/easypost/models/rate.rb +5 -0
  77. data/lib/easypost/models/referral.rb +5 -0
  78. data/lib/easypost/models/refund.rb +5 -0
  79. data/lib/easypost/models/report.rb +5 -0
  80. data/lib/easypost/models/scan_form.rb +6 -0
  81. data/lib/easypost/models/shipment.rb +10 -0
  82. data/lib/easypost/models/tax_identifier.rb +6 -0
  83. data/lib/easypost/models/tracker.rb +5 -0
  84. data/lib/easypost/models/user.rb +5 -0
  85. data/lib/easypost/models/webhook.rb +6 -0
  86. data/lib/easypost/models.rb +36 -0
  87. data/lib/easypost/services/address.rb +50 -0
  88. data/lib/easypost/services/api_key.rb +8 -0
  89. data/lib/easypost/services/base.rb +27 -0
  90. data/lib/easypost/services/batch.rb +53 -0
  91. data/lib/easypost/services/beta_rate.rb +12 -0
  92. data/lib/easypost/services/beta_referral_customer.rb +40 -0
  93. data/lib/easypost/services/billing.rb +75 -0
  94. data/lib/easypost/services/carrier_account.rb +44 -0
  95. data/lib/easypost/services/carrier_metadata.rb +22 -0
  96. data/lib/easypost/services/carrier_type.rb +10 -0
  97. data/lib/easypost/services/customs_info.rb +17 -0
  98. data/lib/easypost/services/customs_item.rb +15 -0
  99. data/lib/easypost/services/end_shipper.rb +31 -0
  100. data/lib/easypost/services/event.rb +32 -0
  101. data/lib/easypost/services/insurance.rb +26 -0
  102. data/lib/easypost/services/order.rb +30 -0
  103. data/lib/easypost/services/parcel.rb +16 -0
  104. data/lib/easypost/services/pickup.rb +40 -0
  105. data/lib/easypost/services/rate.rb +8 -0
  106. data/lib/easypost/services/referral_customer.rb +103 -0
  107. data/lib/easypost/services/refund.rb +26 -0
  108. data/lib/easypost/services/report.rb +42 -0
  109. data/lib/easypost/services/scan_form.rb +25 -0
  110. data/lib/easypost/services/shipment.rb +106 -0
  111. data/lib/easypost/services/tracker.rb +38 -0
  112. data/lib/easypost/services/user.rb +66 -0
  113. data/lib/easypost/services/webhook.rb +34 -0
  114. data/lib/easypost/services.rb +33 -0
  115. data/lib/easypost/util.rb +160 -116
  116. data/lib/easypost/utilities/constants.rb +5 -0
  117. data/lib/easypost/utilities/json.rb +23 -0
  118. data/lib/easypost/utilities/static_mapper.rb +73 -0
  119. data/lib/easypost/utilities/system.rb +36 -0
  120. data/lib/easypost/version.rb +3 -1
  121. data/lib/easypost.rb +20 -143
  122. metadata +249 -46
  123. data/lib/easypost/address.rb +0 -58
  124. data/lib/easypost/api_key.rb +0 -2
  125. data/lib/easypost/batch.rb +0 -49
  126. data/lib/easypost/brand.rb +0 -9
  127. data/lib/easypost/carrier_account.rb +0 -5
  128. data/lib/easypost/carrier_type.rb +0 -2
  129. data/lib/easypost/customs_info.rb +0 -5
  130. data/lib/easypost/customs_item.rb +0 -5
  131. data/lib/easypost/error.rb +0 -31
  132. data/lib/easypost/event.rb +0 -7
  133. data/lib/easypost/insurance.rb +0 -2
  134. data/lib/easypost/object.rb +0 -151
  135. data/lib/easypost/order.rb +0 -28
  136. data/lib/easypost/parcel.rb +0 -2
  137. data/lib/easypost/pickup.rb +0 -26
  138. data/lib/easypost/pickup_rate.rb +0 -3
  139. data/lib/easypost/postage_label.rb +0 -2
  140. data/lib/easypost/print_job.rb +0 -2
  141. data/lib/easypost/printer.rb +0 -24
  142. data/lib/easypost/rate.rb +0 -2
  143. data/lib/easypost/refund.rb +0 -2
  144. data/lib/easypost/report.rb +0 -29
  145. data/lib/easypost/resource.rb +0 -75
  146. data/lib/easypost/scan_form.rb +0 -6
  147. data/lib/easypost/shipment.rb +0 -129
  148. data/lib/easypost/tax_identifier.rb +0 -2
  149. data/lib/easypost/tracker.rb +0 -7
  150. data/lib/easypost/user.rb +0 -56
  151. data/lib/easypost/webhook.rb +0 -29
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'services'
4
+ require_relative 'http_client'
5
+ require_relative 'internal_utilities'
6
+ require 'json'
7
+ require 'securerandom'
8
+
9
+ class EasyPost::Client
10
+ attr_reader :open_timeout, :read_timeout, :api_base
11
+
12
+ # Initialize a new Client object
13
+ # @param api_key [String] the API key to be used for requests
14
+ # @param read_timeout [Integer] (60) the number of seconds to wait for a response before timing out
15
+ # @param open_timeout [Integer] (30) the number of seconds to wait for the connection to open before timing out
16
+ # @param api_base [String] ('https://api.easypost.com') the base URL for the API
17
+ # @param custom_client_exec [Proc] (nil) a custom client execution block to be used for requests instead of the default HTTP client (function signature: method, uri, headers, open_timeout, read_timeout, body = nil)
18
+ # @return [EasyPost::Client] the client object
19
+ def initialize(api_key:, read_timeout: 60, open_timeout: 30, api_base: 'https://api.easypost.com',
20
+ custom_client_exec: nil)
21
+ raise EasyPost::Errors::MissingParameterError.new('api_key') if api_key.nil?
22
+
23
+ @api_key = api_key
24
+ @api_base = api_base
25
+ @api_version = 'v2'
26
+ @read_timeout = read_timeout
27
+ @open_timeout = open_timeout
28
+ @lib_version = File.open(File.expand_path('../../VERSION', __dir__)).read.strip
29
+
30
+ # Make an HTTP client once, reuse it for all requests made by this client
31
+ # Configuration is immutable, so this is safe
32
+ @http_client = EasyPost::HttpClient.new(api_base, http_config, custom_client_exec)
33
+ end
34
+
35
+ SERVICE_CLASSES = [
36
+ EasyPost::Services::Address,
37
+ EasyPost::Services::ApiKey,
38
+ EasyPost::Services::Batch,
39
+ EasyPost::Services::BetaRate,
40
+ EasyPost::Services::BetaReferralCustomer,
41
+ EasyPost::Services::Billing,
42
+ EasyPost::Services::CarrierAccount,
43
+ EasyPost::Services::CarrierMetadata,
44
+ EasyPost::Services::CarrierType,
45
+ EasyPost::Services::CustomsInfo,
46
+ EasyPost::Services::CustomsItem,
47
+ EasyPost::Services::EndShipper,
48
+ EasyPost::Services::Event,
49
+ EasyPost::Services::Insurance,
50
+ EasyPost::Services::Order,
51
+ EasyPost::Services::Parcel,
52
+ EasyPost::Services::Pickup,
53
+ EasyPost::Services::Rate,
54
+ EasyPost::Services::ReferralCustomer,
55
+ EasyPost::Services::Refund,
56
+ EasyPost::Services::Report,
57
+ EasyPost::Services::ScanForm,
58
+ EasyPost::Services::Shipment,
59
+ EasyPost::Services::Tracker,
60
+ EasyPost::Services::User,
61
+ EasyPost::Services::Webhook,
62
+ ].freeze
63
+
64
+ # Loop over the SERVICE_CLASSES to automatically define the method and instance variable instead of manually define it
65
+ SERVICE_CLASSES.each do |cls|
66
+ define_method(EasyPost::InternalUtilities.to_snake_case(cls.name.split('::').last)) do
67
+ instance_variable_set("@#{EasyPost::InternalUtilities.to_snake_case(cls.name.split('::').last)}", cls.new(self))
68
+ end
69
+ end
70
+
71
+ # Make an HTTP request
72
+ #
73
+ # @param method [Symbol] the HTTP Verb (get, method, put, post, etc.)
74
+ # @param endpoint [String] URI path of the resource
75
+ # @param cls [Class] the class to deserialize to
76
+ # @param body [Object] (nil) object to be dumped to JSON
77
+ # @param api_version [String] the version of API to hit
78
+ # @raise [EasyPost::Error] if the response has a non-2xx status code
79
+ # @return [Hash] JSON object parsed from the response body
80
+ def make_request(
81
+ method,
82
+ endpoint,
83
+ cls = EasyPost::Models::EasyPostObject,
84
+ body = nil,
85
+ api_version = EasyPost::InternalUtilities::Constants::API_VERSION
86
+ )
87
+ response = @http_client.request(method, endpoint, nil, body, api_version)
88
+
89
+ potential_error = EasyPost::Errors::ApiError.handle_api_error(response)
90
+ raise potential_error unless potential_error.nil?
91
+
92
+ EasyPost::InternalUtilities::Json.convert_json_to_object(response.body, cls)
93
+ end
94
+
95
+ # Subscribe a request hook
96
+ #
97
+ # @param name [Symbol] the name of the hook. Defaults ot a ranom hexadecimal-based symbol
98
+ # @param block [Block] a code block that will be executed before a request is made
99
+ # @return [Symbol] the name of the request hook
100
+ def subscribe_request_hook(name = SecureRandom.hex.to_sym, &block)
101
+ EasyPost::Hooks.subscribe(:request, name, block)
102
+ end
103
+
104
+ # Unsubscribe a request hook
105
+ #
106
+ # @param name [Symbol] the name of the hook
107
+ # @return [Block] the hook code block
108
+ def unsubscribe_request_hook(name)
109
+ EasyPost::Hooks.unsubscribe(:request, name)
110
+ end
111
+
112
+ # Unsubscribe all request hooks
113
+ #
114
+ # @return [Hash] a hash containing all request hook subscriptions
115
+ def unsubscribe_all_request_hooks
116
+ EasyPost::Hooks.unsubscribe_all(:request)
117
+ end
118
+
119
+ # Subscribe a response hook
120
+ #
121
+ # @param name [Symbol] the name of the hook. Defaults ot a ranom hexadecimal-based symbol
122
+ # @param block [Block] a code block that will be executed upon receiving the response from a request
123
+ # @return [Symbol] the name of the response hook
124
+ def subscribe_response_hook(name = SecureRandom.hex.to_sym, &block)
125
+ EasyPost::Hooks.subscribe(:response, name, block)
126
+ end
127
+
128
+ # Unsubscribe a response hook
129
+ #
130
+ # @param name [Symbol] the name of the hook
131
+ # @return [Block] the hook code block
132
+ def unsubscribe_response_hook(name)
133
+ EasyPost::Hooks.unsubscribe(:response, name)
134
+ end
135
+
136
+ # Unsubscribe all response hooks
137
+ #
138
+ # @return [Hash] a hash containing all response hook subscriptions
139
+ def unsubscribe_all_response_hooks
140
+ EasyPost::Hooks.unsubscribe_all(:response)
141
+ end
142
+
143
+ private
144
+
145
+ def http_config
146
+ http_config = {
147
+ read_timeout: @read_timeout,
148
+ open_timeout: @open_timeout,
149
+ headers: default_headers,
150
+ }
151
+
152
+ http_config[:min_version] = OpenSSL::SSL::TLS1_2_VERSION
153
+ http_config
154
+ end
155
+
156
+ def default_headers
157
+ {
158
+ 'Content-Type' => 'application/json',
159
+ 'User-Agent' => user_agent,
160
+ 'Authorization' => authorization,
161
+ }
162
+ end
163
+
164
+ def user_agent
165
+ ruby_version = EasyPost::InternalUtilities::System.ruby_version
166
+ ruby_patchlevel = EasyPost::InternalUtilities::System.ruby_patchlevel
167
+
168
+ "EasyPost/#{@api_version} " \
169
+ "RubyClient/#{@lib_version} " \
170
+ "Ruby/#{ruby_version}-p#{ruby_patchlevel} " \
171
+ "OS/#{EasyPost::InternalUtilities::System.os_name} " \
172
+ "OSVersion/#{EasyPost::InternalUtilities::System.os_version} " \
173
+ "OSArch/#{EasyPost::InternalUtilities::System.os_arch}"
174
+ end
175
+
176
+ def authorization
177
+ "Bearer #{@api_key}"
178
+ end
179
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ EasyPost::Connection = Struct.new(:uri, :config, keyword_init: true) do
4
+ # Make an HTTP request with Ruby's {Net::HTTP}
5
+ #
6
+ # @param method [Symbol] the HTTP Verb (get, method, put, post, etc.)
7
+ # @param path [String] URI path of the resource
8
+ # @param requested_api_key [String] ({EasyPost.api_key}) key set Authorization header.
9
+ # @param body [String] (nil) body of the request
10
+ # @raise [EasyPost::Error] if the response has a non-2xx status code
11
+ # @return [Hash] JSON object parsed from the response body
12
+ def call(method, path, api_key = nil, body = nil)
13
+ raise EasyPost::Errors::MissingParameterError.new('api_key') if api_key.nil?
14
+
15
+ connection =
16
+ if config[:proxy]
17
+ proxy_uri = URI(config[:proxy])
18
+ Net::HTTP.new(
19
+ uri.host,
20
+ uri.port,
21
+ proxy_uri.host,
22
+ proxy_uri.port,
23
+ proxy_uri.user,
24
+ proxy_uri.password,
25
+ )
26
+ else
27
+ Net::HTTP.new(uri.host, uri.port)
28
+ end
29
+
30
+ connection.use_ssl = true
31
+
32
+ config.each do |name, value|
33
+ # Discrepancies between RestClient and Net::HTTP.
34
+ case name
35
+ when :verify_ssl
36
+ name = :verify_mode
37
+ when :timeout
38
+ name = :read_timeout
39
+ end
40
+
41
+ # Handled in the creation of the client.
42
+ if name == :proxy
43
+ next
44
+ end
45
+
46
+ connection.public_send("#{name}=", value)
47
+ end
48
+
49
+ request = Net::HTTP.const_get(method.capitalize).new(path)
50
+ request.body = JSON.dump(EasyPost::InternalUtilities.objects_to_ids(body)) if body
51
+
52
+ EasyPost.default_headers.each_pair { |h, v| request[h] = v }
53
+ request['Authorization'] = EasyPost.authorization(api_key)
54
+
55
+ response = connection.request(request)
56
+ response_is_json = response['Content-Type'] ? response['Content-Type'].start_with?('application/json') : false
57
+
58
+ EasyPost.parse_response(
59
+ status: response.code.to_i,
60
+ body: response.body,
61
+ json: response_is_json,
62
+ )
63
+ end
64
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Constants
4
+ API_ERROR_DETAILS_PARSING_ERROR = 'API error details could not be parsed.'
5
+ INVALID_PARAMETER = '%s is not a valid parameter.'
6
+ INVALID_PAYMENT_METHOD = 'The chosen payment method is not valid. Please try again.'
7
+ MISSING_REQUIRED_PARAMETER = 'Required parameter %s is missing.'
8
+ NO_MATCHING_RATES = 'No matching rates found.'
9
+ NO_MORE_PAGES = 'There are no more pages to retrieve.'
10
+ NO_PAYMENT_METHODS = 'Billing has not been setup for this user. Please add a payment method.'
11
+ STRIPE_CARD_CREATE_FAILED = 'Could not send card details to Stripe, please try again later.'
12
+ UNEXPECTED_HTTP_STATUS_CODE = 'Unexpected HTTP status code received: %s'
13
+ WEBHOOK_MISSING_SIGNATURE = 'Webhook received does not contain an HMAC signature.'
14
+ WEBHOOK_SIGNATURE_MISMATCH = 'Webhook received did not originate from EasyPost or had a webhook secret mismatch.'
15
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../easy_post_error'
4
+ require 'easypost/constants'
5
+
6
+ class EasyPost::Errors::ApiError < EasyPost::Errors::EasyPostError
7
+ attr_reader :status_code, :code, :errors
8
+
9
+ def initialize(message, status_code = nil, error_code = nil, sub_errors = nil)
10
+ super message
11
+ @status_code = status_code
12
+ @code = error_code
13
+ @errors = sub_errors
14
+ end
15
+
16
+ def pretty_print
17
+ error_string = "#{code} (#{status_code}): #{message}"
18
+ errors&.each do |error|
19
+ error_string += "\nField: #{error.field}\nMessage: #{error.message}"
20
+ end
21
+ error_string
22
+ end
23
+
24
+ # Recursively traverses a JSON element to extract error messages and returns them as a comma-separated string.
25
+ def self.collect_error_messages(error_message, messages_list)
26
+ case error_message
27
+ when Hash
28
+ error_message.each_value { |value| collect_error_messages(value, messages_list) }
29
+ when Array
30
+ error_message.each { |value| collect_error_messages(value, messages_list) }
31
+ else
32
+ messages_list.push(error_message.to_s)
33
+ end
34
+
35
+ messages_list.join(', ')
36
+ end
37
+
38
+ def self.handle_api_error(response)
39
+ status_code = response.code
40
+ status_code = status_code.to_i if status_code.is_a?(String)
41
+
42
+ if status_code >= 200 && status_code <= 299
43
+ return nil
44
+ end
45
+
46
+ # Try to parse the response body as JSON
47
+ begin
48
+ error_data = JSON.parse(response.body)['error']
49
+
50
+ error_message = error_data['message']
51
+ error_type = error_data['code']
52
+ errors = error_data['errors']&.map do |error|
53
+ EasyPost::Models::Error.from_api_error_response(error)
54
+ end
55
+ rescue StandardError
56
+ error_message = response.code.to_s
57
+ error_type = EasyPost::Constants::API_ERROR_DETAILS_PARSING_ERROR
58
+ errors = nil
59
+ end
60
+
61
+ cls = exception_cls_from_status_code(status_code)
62
+
63
+ if cls == EasyPost::Errors::UnknownApiError
64
+ return EasyPost::Errors::UnknownApiError.new(
65
+ EasyPost::Constants::UNEXPECTED_HTTP_STATUS_CODE % status_code,
66
+ status_code,
67
+ )
68
+ end
69
+
70
+ # Return (don't throw here) an instance of the appropriate error class
71
+ cls.new(error_message, status_code, error_type, errors)
72
+ end
73
+
74
+ def self.exception_cls_from_status_code(status_code)
75
+ case status_code
76
+ when 0
77
+ EasyPost::Errors::ConnectionError
78
+ when 300, 301, 302, 303, 304, 305, 306, 307, 308
79
+ EasyPost::Errors::RedirectError
80
+ when 400
81
+ EasyPost::Errors::BadRequestError
82
+ when 401
83
+ EasyPost::Errors::UnauthorizedError
84
+ when 402
85
+ EasyPost::Errors::PaymentError
86
+ when 403
87
+ EasyPost::Errors::ForbiddenError
88
+ when 404
89
+ EasyPost::Errors::NotFoundError
90
+ when 405
91
+ EasyPost::Errors::MethodNotAllowedError
92
+ when 408
93
+ EasyPost::Errors::TimeoutError
94
+ when 422
95
+ EasyPost::Errors::InvalidRequestError
96
+ when 429
97
+ EasyPost::Errors::RateLimitError
98
+ when 500
99
+ EasyPost::Errors::InternalServerError
100
+ when 502, 504
101
+ EasyPost::Errors::GatewayTimeoutError
102
+ when 503
103
+ EasyPost::Errors::ServiceUnavailableError
104
+ else
105
+ EasyPost::Errors::UnknownApiError
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::BadRequestError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::ConnectionError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Errors::ExternalApiError < EasyPost::Errors::EasyPostError
4
+ attr_reader :status_code
5
+
6
+ def initialize(message, status_code = nil)
7
+ super message
8
+ @status_code = status_code
9
+ end
10
+
11
+ def pretty_print
12
+ if status_code.nil?
13
+ return message
14
+ end
15
+
16
+ "(#{status_code}): #{message}"
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::ForbiddenError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::GatewayTimeoutError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::InternalServerError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::InvalidRequestError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::MethodNotAllowedError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::NotFoundError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::PaymentError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::ProxyError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::RateLimitError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::RedirectError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::RetryError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::ServiceUnavailableError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::SslError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::TimeoutError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::UnauthorizedError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_error'
4
+
5
+ class EasyPost::Errors::UnknownApiError < EasyPost::Errors::ApiError
6
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Errors::EasyPostError < StandardError
4
+ def pretty_print
5
+ message.to_s
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Errors::EndOfPaginationError < EasyPost::Errors::EasyPostError
4
+ def initialize
5
+ super EasyPost::Constants::NO_MORE_PAGES
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Errors::FilteringError < EasyPost::Errors::EasyPostError
4
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Errors::InvalidObjectError < EasyPost::Errors::EasyPostError
4
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'easypost/constants'
4
+
5
+ class EasyPost::Errors::InvalidParameterError < EasyPost::Errors::EasyPostError
6
+ # @param [String] parameter The name of the parameter that was invalid.
7
+ # @param [String] suggestion Optional suggestion message for a valid parameter.
8
+ def initialize(parameter, suggestion = nil)
9
+ super EasyPost::Constants::INVALID_PARAMETER % parameter + (suggestion.nil? ? '' : " #{suggestion}")
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'easypost/constants'
4
+
5
+ class EasyPost::Errors::MissingParameterError < EasyPost::Errors::EasyPostError
6
+ def initialize(parameter)
7
+ super EasyPost::Constants::MISSING_REQUIRED_PARAMETER % parameter
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Errors::SignatureVerificationError < EasyPost::Errors::EasyPostError
4
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EasyPost::Errors
4
+ end
5
+
6
+ require_relative 'errors/easy_post_error'
7
+ require_relative 'errors/end_of_pagination_error'
8
+ require_relative 'errors/api/external_api_error'
9
+ require_relative 'errors/filtering_error'
10
+ require_relative 'errors/invalid_object_error'
11
+ require_relative 'errors/invalid_parameter_error'
12
+ require_relative 'errors/missing_parameter_error'
13
+ require_relative 'errors/signature_verification_error'
14
+ require_relative 'errors/api/api_error'
15
+ require_relative 'errors/api/bad_request_error'
16
+ require_relative 'errors/api/connection_error'
17
+ require_relative 'errors/api/forbidden_error'
18
+ require_relative 'errors/api/gateway_timeout_error'
19
+ require_relative 'errors/api/internal_server_error'
20
+ require_relative 'errors/api/invalid_request_error'
21
+ require_relative 'errors/api/method_not_allowed_error'
22
+ require_relative 'errors/api/not_found_error'
23
+ require_relative 'errors/api/payment_error'
24
+ require_relative 'errors/api/proxy_error'
25
+ require_relative 'errors/api/rate_limit_error'
26
+ require_relative 'errors/api/redirect_error'
27
+ require_relative 'errors/api/retry_error'
28
+ require_relative 'errors/api/service_unavailable_error'
29
+ require_relative 'errors/api/ssl_error'
30
+ require_relative 'errors/api/timeout_error'
31
+ require_relative 'errors/api/unauthorized_error'
32
+ require_relative 'errors/api/unknown_api_error'
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Hooks::RequestContext
4
+ attr_reader :method, :path, :headers, :request_body, :request_timestamp, :request_uuid
5
+
6
+ def initialize(method:, path:, headers:, request_body:, request_timestamp:, request_uuid:)
7
+ @method = method
8
+ @path = path
9
+ @headers = headers
10
+ @request_body = request_body
11
+ @request_timestamp = request_timestamp
12
+ @request_uuid = request_uuid
13
+
14
+ freeze
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EasyPost::Hooks::ResponseContext
4
+ attr_reader :http_status, :method, :path, :headers, :response_body,
5
+ :request_timestamp, :response_timestamp, :request_uuid,
6
+ :client_response_object
7
+
8
+ def initialize(http_status:, method:, path:, headers:, response_body:,
9
+ request_timestamp:, response_timestamp:, request_uuid:,
10
+ client_response_object:)
11
+ @http_status = http_status
12
+ @method = method
13
+ @path = path
14
+ @headers = headers
15
+ @response_body = response_body
16
+ @request_timestamp = request_timestamp
17
+ @response_timestamp = response_timestamp
18
+ @request_uuid = request_uuid
19
+ @client_response_object = client_response_object
20
+
21
+ freeze
22
+ end
23
+ end