@@ -215,47 +215,79 @@ def persistent?
215215 # @param [Hash] params custom search inputs
216216 # @return [String|Hash] raw HTML or decoded response as JSON / Hash
217217 def get ( endpoint , decoder = :json , params = { } )
218- # execute get via open socket
219- response = if persistent?
220- @socket . get ( endpoint , params : query ( params ) )
221- else
222- HTTP . timeout ( timeout ) . get ( "https://#{ BACKEND } #{ endpoint } " , params : query ( params ) )
223- end
224-
225- # decode response using JSON native parser
218+ response = execute_request ( endpoint , params )
219+ handle_response ( response , decoder , endpoint , params )
220+ end
221+
222+ def execute_request ( endpoint , params )
223+ if persistent?
224+ @socket . get ( endpoint , params : query ( params ) )
225+ else
226+ url = "https://#{ BACKEND } #{ endpoint } "
227+ HTTP . timeout ( timeout ) . get ( url , params : query ( params ) )
228+ end
229+ end
230+
231+ def handle_response ( response , decoder , endpoint , params )
226232 case decoder
227233 when :json
228- # read http response
229- begin
230- # user can turn on/off JSON keys to symbols
231- # this is more memory efficient, but not always needed
232- symbolize_names = params . key? ( :symbolize_names ) ? params [ :symbolize_names ] : true
233-
234- # parse JSON response with Ruby standard library
235- data = JSON . parse ( response . body , symbolize_names : symbolize_names )
236- if data . instance_of? ( Hash ) && data . key? ( :error )
237- raise SerpApiError , "HTTP request failed with error: #{ data [ :error ] } from url: https://#{ BACKEND } #{ endpoint } , params: #{ params } , decoder: #{ decoder } , response status: #{ response . status } "
238- elsif response . status != 200
239- raise SerpApiError , "HTTP request failed with response status: #{ response . status } reponse: #{ data } on get url: https://#{ BACKEND } #{ endpoint } , params: #{ params } , decoder: #{ decoder } "
240- end
241- rescue JSON ::ParserError
242- raise SerpApiError , "JSON parse error: #{ response . body } on get url: https://#{ BACKEND } #{ endpoint } , params: #{ params } , decoder: #{ decoder } , response status: #{ response . status } "
243- end
244-
245- # discard response body
246- response . flush if persistent?
247-
248- data
234+ process_json_response ( response , endpoint , params )
249235 when :html
250- # html decoder
251- if response . status != 200
252- raise SerpApiError , "HTTP request failed with response status: #{ response . status } reponse: #{ data } on get url: https://#{ BACKEND } #{ endpoint } , params: #{ params } , decoder: #{ decoder } "
253- end
254-
255- response . body
236+ process_html_response ( response , endpoint , params )
256237 else
257238 raise SerpApiError , "not supported decoder: #{ decoder } , available: :json, :html"
258239 end
259240 end
241+
242+ def process_json_response ( response , endpoint , params )
243+ symbolize = params . fetch ( :symbolize_names , true )
244+
245+ begin
246+ data = JSON . parse ( response . body , symbolize_names : symbolize )
247+ validate_json_content! ( data , response , endpoint , params )
248+ rescue JSON ::ParserError
249+ raise_parser_error ( response , endpoint , params )
250+ end
251+
252+ response . flush if persistent?
253+ data
254+ end
255+
256+ def process_html_response ( response , endpoint , params )
257+ raise_http_error ( response , nil , endpoint , params , decoder : :html ) if response . status != 200
258+ response . body
259+ end
260+
261+ def validate_json_content! ( data , response , endpoint , params )
262+ if data . is_a? ( Hash ) && data . key? ( :error )
263+ raise_http_error ( response , data , endpoint , params , explicit_error : data [ :error ] )
264+ elsif response . status != 200
265+ raise_http_error ( response , data , endpoint , params )
266+ end
267+ end
268+
269+ # Centralized error raising to clean up the logic methods
270+ def raise_http_error ( response , data , endpoint , params , explicit_error : nil , decoder : :json )
271+ msg = "HTTP request failed with status: #{ response . status } "
272+ msg += " error: #{ explicit_error } " if explicit_error
273+
274+ raise SerpApiError . new (
275+ "#{ msg } from url: https://#{ BACKEND } #{ endpoint } " ,
276+ serpapi_error : explicit_error || ( data . is_a? ( Hash ) ? data [ :error ] : nil ) ,
277+ search_params : params ,
278+ response_status : response . status ,
279+ search_id : data . is_a? ( Hash ) ? data &.dig ( :search_metadata , :id ) : nil ,
280+ decoder : decoder
281+ )
282+ end
283+
284+ def raise_parser_error ( response , endpoint , params )
285+ raise SerpApiError . new (
286+ "JSON parse error: #{ response . body } on get url: https://#{ BACKEND } #{ endpoint } " ,
287+ search_params : params ,
288+ response_status : response . status ,
289+ decoder : :json
290+ )
291+ end
260292 end
261293end
0 commit comments