1
1
# frozen_string_literal: true
2
2
3
- require 'typhoeus '
3
+ require 'faraday '
4
4
require 'oj'
5
5
6
6
module Typesense
@@ -69,23 +69,25 @@ def perform_request(method, endpoint, query_parameters: nil, body_parameters: ni
69
69
@logger . debug "Attempting #{ method . to_s . upcase } request Try ##{ num_tries } to Node #{ node [ :index ] } "
70
70
71
71
begin
72
- request_options = {
73
- method : method ,
74
- timeout : @connection_timeout_seconds ,
75
- headers : default_headers . merge ( additional_headers )
76
- }
77
- request_options . merge! ( params : query_parameters ) unless query_parameters . nil?
78
-
79
- unless body_parameters . nil?
80
- body = body_parameters
81
- body = Oj . dump ( body_parameters , mode : :compat ) if request_options [ :headers ] [ 'Content-Type' ] == 'application/json'
82
- request_options . merge! ( body : body )
72
+ conn = Faraday . new ( uri_for ( endpoint , node ) ) do |f |
73
+ f . options . timeout = @connection_timeout_seconds
74
+ f . options . open_timeout = @connection_timeout_seconds
83
75
end
84
76
85
- response = Typhoeus ::Request . new ( uri_for ( endpoint , node ) , request_options ) . run
86
- set_node_healthcheck ( node , is_healthy : true ) if response . code >= 1 && response . code <= 499
77
+ headers = default_headers . merge ( additional_headers )
87
78
88
- @logger . debug "Request #{ method } :#{ uri_for ( endpoint , node ) } to Node #{ node [ :index ] } was successfully made (at the network layer). Response Code was #{ response . code } ."
79
+ response = conn . send ( method ) do |req |
80
+ req . headers = headers
81
+ req . params = query_parameters unless query_parameters . nil?
82
+ unless body_parameters . nil?
83
+ body = body_parameters
84
+ body = Oj . dump ( body_parameters , mode : :compat ) if headers [ 'Content-Type' ] == 'application/json'
85
+ req . body = body
86
+ end
87
+ end
88
+ set_node_healthcheck ( node , is_healthy : true ) if response . status >= 1 && response . status <= 499
89
+
90
+ @logger . debug "Request #{ method } :#{ uri_for ( endpoint , node ) } to Node #{ node [ :index ] } was successfully made (at the network layer). response.status was #{ response . status } ."
89
91
90
92
parsed_response = if response . headers && ( response . headers [ 'content-type' ] || '' ) . include? ( 'application/json' )
91
93
Oj . load ( response . body , mode : :compat )
@@ -94,13 +96,15 @@ def perform_request(method, endpoint, query_parameters: nil, body_parameters: ni
94
96
end
95
97
96
98
# If response is 2xx return the object, else raise the response as an exception
97
- return parsed_response if response . code >= 200 && response . code <= 299
99
+ return parsed_response if response . status >= 200 && response . status <= 299
98
100
99
101
exception_message = ( parsed_response && parsed_response [ 'message' ] ) || 'Error'
100
102
raise custom_exception_klass_for ( response ) , exception_message
101
- rescue Errno ::EINVAL , Errno ::ENETDOWN , Errno ::ENETUNREACH , Errno ::ENETRESET , Errno ::ECONNABORTED , Errno ::ECONNRESET ,
102
- Errno ::ETIMEDOUT , Errno ::ECONNREFUSED , Errno ::EHOSTDOWN , Errno ::EHOSTUNREACH ,
103
- Typesense ::Error ::TimeoutError , Typesense ::Error ::ServerError , Typesense ::Error ::HTTPStatus0Error => e
103
+ rescue Faraday ::ConnectionFailed , Faraday ::TimeoutError ,
104
+ Errno ::EINVAL , Errno ::ENETDOWN , Errno ::ENETUNREACH , Errno ::ENETRESET ,
105
+ Errno ::ECONNABORTED , Errno ::ECONNRESET , Errno ::ETIMEDOUT ,
106
+ Errno ::ECONNREFUSED , Errno ::EHOSTDOWN , Errno ::EHOSTUNREACH ,
107
+ Typesense ::Error ::ServerError , Typesense ::Error ::HTTPStatus0Error => e
104
108
# Rescue network layer exceptions and HTTP 5xx errors, so the loop can continue.
105
109
# Using loops for retries instead of rescue...retry to maintain consistency with client libraries in
106
110
# other languages that might not support the same construct.
@@ -176,23 +180,24 @@ def set_node_healthcheck(node, is_healthy:)
176
180
end
177
181
178
182
def custom_exception_klass_for ( response )
179
- if response . code == 400
183
+ if response . status == 400
180
184
Typesense ::Error ::RequestMalformed . new ( response : response )
181
- elsif response . code == 401
185
+ elsif response . status == 401
182
186
Typesense ::Error ::RequestUnauthorized . new ( response : response )
183
- elsif response . code == 404
187
+ elsif response . status == 404
184
188
Typesense ::Error ::ObjectNotFound . new ( response : response )
185
- elsif response . code == 409
189
+ elsif response . status == 409
186
190
Typesense ::Error ::ObjectAlreadyExists . new ( response : response )
187
- elsif response . code == 422
191
+ elsif response . status == 422
188
192
Typesense ::Error ::ObjectUnprocessable . new ( response : response )
189
- elsif response . code >= 500 && response . code <= 599
193
+ elsif response . status >= 500 && response . status <= 599
190
194
Typesense ::Error ::ServerError . new ( response : response )
191
- elsif response . timed_out?
195
+ elsif response . respond_to? ( :timed_out? ) && response . timed_out?
192
196
Typesense ::Error ::TimeoutError . new ( response : response )
193
- elsif response . code . zero?
197
+ elsif response . status . zero?
194
198
Typesense ::Error ::HTTPStatus0Error . new ( response : response )
195
199
else
200
+ # This will handle both 300-level responses and any other unhandled status codes
196
201
Typesense ::Error ::HTTPError . new ( response : response )
197
202
end
198
203
end
0 commit comments