typeform_data 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d70cdb5034873b422938f7cf426b0b1341a992ab
4
- data.tar.gz: a36e89135238d96c2ebe7ea0466c56fbf2f2b23f
3
+ metadata.gz: 3da62092341167802dd4565276637320bc9b4239
4
+ data.tar.gz: c60c7c72ddc21e7732f2ea866639f3c404879706
5
5
  SHA512:
6
- metadata.gz: 5ec3a03e56573d5b75fed0aff79d2f1a54dfeb176433c7afc1621e6532a76e7fb31a0ca9ca8477ca41c78ba04b9ef8b05ea4b0b5c9c88df2a7e870ea3ea47ed1
7
- data.tar.gz: 38532360add588301c0e3c3621088e72dba3ccc7758cecd1a84f43ae4eb27a4824010a32db4ae0d874088573f5a6b3fd1ebf14ec517ed3b869f989124394858a
6
+ metadata.gz: 0b423251f537bb0b5a2a041fa2a80f57ffceefd70c33c886c0fdfc4c7f8df52770148c021f03b8f7d5ee8fa3cf04b9b673ef1cdc713eeffafe154f082e6ecf72
7
+ data.tar.gz: 1ce2a17d3b448d5a0fa4a2c8aae6d2dcd22026f0590d9d1aaae0a10b652c8114d6a2be4de0bc1d3ecc5f9d9e64443123b11b56e1a2588aa44976b590b5cb4fad
data/README.md CHANGED
@@ -68,6 +68,15 @@ Unless you've encountered a bug, all exceptions raised by this gem should extend
68
68
 
69
69
  If a HTTP request to Typeform fails with an error that we expect to be transient (e.g. a 503) we retry the HTTP request up to 3 times, after waiting 1, 2 and 4 seconds. If you'd prefer a fail-fast approach, send us a PR!
70
70
 
71
+ Currently, all 404 errors are retried. This is because Typeform occasionally returns a 404 while it's waiting to achieve consistency. For more, see `lib/typeform_data/requestor.rb`.
72
+
73
+ ### Logging
74
+
75
+ This gem logs error and warning messages to $stdout by default. If you want to log to elsewhere, or in a different format, you can pass in your own logger object (anything that implements the same interface as the [default Ruby logger](https://ruby-doc.org/stdlib-2.1.0/libdoc/logger/rdoc/Logger.html)) like this:
76
+
77
+ ```
78
+ TypeformData::Client.new(api_key: 'YOUR API KEY', logger: logger)
79
+ ```
71
80
 
72
81
  ## Notes on the API
73
82
 
@@ -6,13 +6,16 @@ module TypeformData
6
6
 
7
7
  # For the sake of usability, we're breaking convention here and accepting an API key as the
8
8
  # first parameter instead of an instance of TypeformData::Config.
9
- def initialize(api_key:)
10
- @config = TypeformData::Config.new(api_key: api_key)
9
+ # @param api_key [String]
10
+ # @param logger [Object] Should implement the same API as
11
+ # https://ruby-doc.org/stdlib-2.1.0/libdoc/logger/rdoc/Logger.html)
12
+ def initialize(api_key:, logger: nil)
13
+ @config = TypeformData::Config.new(api_key: api_key, logger: logger)
11
14
  end
12
15
 
13
16
  def self.new_from_config(config)
14
17
  raise TypeformData::ArgumentError, 'Missing config' unless config
15
- new(api_key: config.api_key)
18
+ new(api_key: config.api_key, logger: config.logger)
16
19
  end
17
20
 
18
21
  # Your API key will automatically be added to the request URL as a query param, as required by
@@ -1,13 +1,20 @@
1
1
  # frozen_string_literal: true
2
+ require 'logger'
3
+
2
4
  module TypeformData
3
5
  class Config
4
6
  attr_reader :api_key
7
+ attr_reader :logger
5
8
 
6
- def initialize(api_key:)
9
+ # @param api_key [String]
10
+ # @param logger [Object] Should implement the same API as
11
+ # https://ruby-doc.org/stdlib-2.1.0/libdoc/logger/rdoc/Logger.html
12
+ def initialize(api_key:, logger: nil)
7
13
  unless api_key.is_a?(String) && api_key.length.positive?
8
14
  raise TypeformData::ArgumentError, 'An API key (as a nonempty String) is required'
9
15
  end
10
16
  @api_key = api_key
17
+ @logger = logger || Logger.new($stdout)
11
18
  end
12
19
 
13
20
  # These values were determined via URI.parse('https://api.typeform.com').
@@ -11,12 +11,19 @@ module TypeformData
11
11
 
12
12
  Errno::ECONNREFUSED,
13
13
  TypeformData::TransientResponseError,
14
+
15
+ # Sometimes it takes a while before Typeform's state becomes consistent. In particular, this
16
+ # can be an issue if you receive a webhook for a form response, then immediately request that
17
+ # response from Typeform's servers.
18
+ TypeformData::InvalidEndpointOrMissingResource,
14
19
  ].freeze
15
20
 
16
- RETRY_RESPONSE_CLASSES = [
21
+ TRANSIENT_RESPONSE_CLASSES = [
17
22
  Net::HTTPServiceUnavailable,
18
23
  Net::HTTPTooManyRequests,
19
24
  Net::HTTPBadGateway,
25
+ Net::HTTPGatewayTimeOut,
26
+ Net::HTTPInternalServerError,
20
27
  ].freeze
21
28
 
22
29
  def self.get(config, endpoint, params = nil)
@@ -34,7 +41,7 @@ module TypeformData
34
41
  params[:key] = config.api_key
35
42
 
36
43
  begin
37
- Utils.retry_with_exponential_backoff(RETRY_EXCEPTIONS, max_retries: 3) do
44
+ Utils.retry_with_exponential_backoff(config, RETRY_EXCEPTIONS, max_retries: 3) do
38
45
  request_and_validate_response(config, method_class, path, params)
39
46
  end
40
47
  rescue *RETRY_EXCEPTIONS => error
@@ -58,7 +65,7 @@ module TypeformData
58
65
  when Net::HTTPBadRequest
59
66
  raise TypeformData::BadRequest, 'Response was a Net::HTTPBadRequest with body: '\
60
67
  "#{response.body}. Your request with params: #{params} could not be processed."
61
- when *RETRY_RESPONSE_CLASSES
68
+ when *TRANSIENT_RESPONSE_CLASSES
62
69
  raise TypeformData::TransientResponseError, "Response was a #{response.class} "\
63
70
  "(code #{response.code}) with message #{response.message}"
64
71
  else
@@ -3,16 +3,20 @@ module Utils
3
3
 
4
4
  # Repeats the block until it succeeds or a limit is reached, waiting twice as long as it
5
5
  # previously did after each failure.
6
+ # @param config [TypeformData::Config]
6
7
  # @param rescued_exceptions [Class] Subclasses of Exception.
7
8
  # @param max_retries [Integer]
8
9
  # @param initial_wait [Integer] In seconds.
9
- def self.retry_with_exponential_backoff(rescued_exceptions, max_retries: 5, initial_wait: 1)
10
+ def self.retry_with_exponential_backoff(config, retry_exceptions, max_retries: 5, initial_wait: 1)
10
11
  seconds_to_wait = initial_wait
11
12
 
12
13
  max_retries.times do |iteration|
13
14
  begin
14
15
  break yield
15
- rescue *rescued_exceptions
16
+ rescue *retry_exceptions
17
+ config.logger.warn "Retry. Waiting #{seconds_to_wait}s, attempt #{iteration} of "\
18
+ "#{max_retries}."
19
+
16
20
  sleep seconds_to_wait
17
21
  seconds_to_wait *= 2
18
22
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module TypeformData
3
- VERSION = '2.0.0'
3
+ VERSION = '3.0.0'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typeform_data
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Wallace
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-10 00:00:00.000000000 Z
11
+ date: 2017-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler