@@ -215,71 +215,81 @@ 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 . new ( "HTTP request failed with error: #{ data [ :error ] } from url: " +
238- "https://#{ BACKEND } #{ endpoint } , params: #{ params } , decoder: " +
239- "#{ decoder } , response status: #{ response . status } " ,
240- serpapi_error : data [ :error ] ,
241- search_params : params ,
242- response_status : response . status ,
243- search_id : data . dig ( :search_metadata , :id ) ,
244- decoder : decoder )
245- elsif response . status != 200
246- raise SerpApiError . new ( "HTTP request failed with response status: #{ response . status } " +
247- " reponse: #{ data } on get url: https://#{ BACKEND } #{ endpoint } , " +
248- "params: #{ params } , decoder: #{ decoder } " ,
249- serpapi_error : data [ :error ] ,
250- search_params : params ,
251- response_status : response . status ,
252- search_id : data . dig ( :search_metadata , :id ) ,
253- decoder : decoder )
254- end
255- rescue JSON ::ParserError
256- raise SerpApiError . new ( "JSON parse error: #{ response . body } on get url: " +
257- "https://#{ BACKEND } #{ endpoint } , params: #{ params } , " +
258- "decoder: #{ decoder } , response status: #{ response . status } " ,
259- search_params : params ,
260- response_status : response . status ,
261- decoder : decoder )
262- end
263-
264- # discard response body
265- response . flush if persistent?
266-
267- data
234+ process_json_response ( response , endpoint , params )
268235 when :html
269- # html decoder
270- if response . status != 200
271- raise SerpApiError . new ( "HTTP request failed with response status: #{ response . status } " +
272- "reponse: #{ data } on get url: https://#{ BACKEND } #{ endpoint } , " +
273- "params: #{ params } , decoder: #{ decoder } " ,
274- search_params : params ,
275- response_status : response . status ,
276- decoder : decoder )
277- end
278-
279- response . body
236+ process_html_response ( response , endpoint , params )
280237 else
281238 raise SerpApiError , "not supported decoder: #{ decoder } , available: :json, :html"
282239 end
283240 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 ) if response . status != 200
258+ response . body
259+ end
260+
261+ def validate_json_content! ( data , response , endpoint , params )
262+ # Check for API-level error inside the JSON
263+ if data . is_a? ( Hash ) && data . key? ( :error )
264+ raise_http_error ( response , data , endpoint , params , explicit_error : data [ :error ] )
265+ # Check for HTTP-level error
266+ elsif response . status != 200
267+ raise_http_error ( response , data , endpoint , params )
268+ end
269+ end
270+
271+ # Centralized error raising to clean up the logic methods
272+ def raise_http_error ( response , data , endpoint , params , explicit_error : nil )
273+ msg = "HTTP request failed with status: #{ response . status } "
274+ msg += " error: #{ explicit_error } " if explicit_error
275+
276+ raise SerpApiError . new (
277+ "#{ msg } from url: https://#{ BACKEND } #{ endpoint } " ,
278+ serpapi_error : explicit_error || ( data ? data [ :error ] : nil ) ,
279+ search_params : params ,
280+ response_status : response . status ,
281+ search_id : data &.dig ( :search_metadata , :id ) ,
282+ decoder : :json # Assuming JSON based on context of use in original code
283+ )
284+ end
285+
286+ def raise_parser_error ( response , endpoint , params )
287+ raise SerpApiError . new (
288+ "JSON parse error: #{ response . body } on get url: https://#{ BACKEND } #{ endpoint } " ,
289+ search_params : params ,
290+ response_status : response . status ,
291+ decoder : :json
292+ )
293+ end
284294 end
285295end
0 commit comments