11# frozen_string_literal: true
22
3- require 'typhoeus '
3+ require 'faraday '
44require 'oj'
55
66module Typesense
@@ -69,23 +69,25 @@ def perform_request(method, endpoint, query_parameters: nil, body_parameters: ni
6969 @logger . debug "Attempting #{ method . to_s . upcase } request Try ##{ num_tries } to Node #{ node [ :index ] } "
7070
7171 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
8375 end
8476
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 )
8778
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 } ."
8991
9092 parsed_response = if response . headers && ( response . headers [ 'content-type' ] || '' ) . include? ( 'application/json' )
9193 Oj . load ( response . body , mode : :compat )
@@ -94,13 +96,15 @@ def perform_request(method, endpoint, query_parameters: nil, body_parameters: ni
9496 end
9597
9698 # 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
98100
99101 exception_message = ( parsed_response && parsed_response [ 'message' ] ) || 'Error'
100102 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
104108 # Rescue network layer exceptions and HTTP 5xx errors, so the loop can continue.
105109 # Using loops for retries instead of rescue...retry to maintain consistency with client libraries in
106110 # other languages that might not support the same construct.
@@ -176,23 +180,24 @@ def set_node_healthcheck(node, is_healthy:)
176180 end
177181
178182 def custom_exception_klass_for ( response )
179- if response . code == 400
183+ if response . status == 400
180184 Typesense ::Error ::RequestMalformed . new ( response : response )
181- elsif response . code == 401
185+ elsif response . status == 401
182186 Typesense ::Error ::RequestUnauthorized . new ( response : response )
183- elsif response . code == 404
187+ elsif response . status == 404
184188 Typesense ::Error ::ObjectNotFound . new ( response : response )
185- elsif response . code == 409
189+ elsif response . status == 409
186190 Typesense ::Error ::ObjectAlreadyExists . new ( response : response )
187- elsif response . code == 422
191+ elsif response . status == 422
188192 Typesense ::Error ::ObjectUnprocessable . new ( response : response )
189- elsif response . code >= 500 && response . code <= 599
193+ elsif response . status >= 500 && response . status <= 599
190194 Typesense ::Error ::ServerError . new ( response : response )
191- elsif response . timed_out?
195+ elsif response . respond_to? ( :timed_out? ) && response . timed_out?
192196 Typesense ::Error ::TimeoutError . new ( response : response )
193- elsif response . code . zero?
197+ elsif response . status . zero?
194198 Typesense ::Error ::HTTPStatus0Error . new ( response : response )
195199 else
200+ # This will handle both 300-level responses and any other unhandled status codes
196201 Typesense ::Error ::HTTPError . new ( response : response )
197202 end
198203 end
0 commit comments