@@ -321,20 +321,78 @@ public function consume($resource, $data = [], array $headers = [], $method = nu
321321 $ options [\GuzzleHttp \RequestOptions::JSON ] = $ data ;
322322 }
323323
324- // realizar consulta HTTP
325- try {
326- $ this ->last_response = $ client ->request ($ method , $ this ->last_url , $ options );
327- } catch (\GuzzleHttp \Exception \GuzzleException $ e ) {
328- $ this ->last_response = $ e ->getResponse ();
329- $ this ->throwException ();
330- }
324+ // realizar consulta HTTP con reintento por si falla la sesión del SII.
325+ foreach ([true , false ] as $ auth_cache ) {
326+
327+ // Forzar el valor de auth_cache en la llamada a la API.
328+ $ this ->last_url = $ this ->forceUrlParams ($ this ->last_url , [
329+ 'auth_cache ' => (int )$ auth_cache ,
330+ ]);
331+
332+ // Ejecutar consulta al SII.
333+ try {
334+ $ this ->last_response = $ client ->request ($ method , $ this ->last_url , $ options );
335+ } catch (\GuzzleHttp \Exception \GuzzleException $ e ) {
336+ // Obtener la respuesta de la llamada.
337+ $ this ->last_response = $ e ->getResponse ();
338+
339+ // Si es un error HTTP 401 con problema de sesión pasamos a la otra iteración
340+ // del ciclo foreach para reintentar sin caché de sesión del SII.
341+ if ($ this ->getLastResponse ()->getStatusCode () == 401 ) {
342+ if ($ this ->getLastResponse ()->getHeaderLine ('X-Stats-NavegadorSessionProblem ' )) {
343+ continue ;
344+ }
345+ }
346+
347+ // Si no es un error 401 con problema de sesión se lanza la excepción.
348+ $ this ->throwException ();
349+ }
331350
332- if ($ this ->getLastResponse ()->getStatusCode () != 200 ) {
351+ // Break obligatorio, ya que si la llamada es exitosa no se debe reintentar.
352+ if ($ this ->getLastResponse ()->getStatusCode () == 200 ) {
353+ break ;
354+ }
355+
356+ // Si no se reintentó se lanza excepción por no ser código 200 (break anterior).
333357 $ this ->throwException ();
334358 }
359+
360+ // Entregar respuesta (contenida en el mismo objeto del cliente).
335361 return $ this ;
336362 }
337363
364+ /**
365+ * Fuerza parámetros específicos en la URL dada.
366+ *
367+ * @param string $url La URL original a modificar.
368+ * @param array $params Arreglo asociativo de parámetros para añadir a la URL.
369+ * @return string La URL modificada con los nuevos parámetros.
370+ */
371+ private function forceUrlParams (string $ url , array $ params ): string
372+ {
373+ // Parsear la URL para extraer componentes.
374+ $ parsedUrl = parse_url ($ url );
375+
376+ // Parsear la cadena de consulta existente y obtener los parámetros actuales.
377+ parse_str ($ parsedUrl ['query ' ] ?? '' , $ queryParams );
378+
379+ // Fusionar los parámetros existentes con los nuevos parámetros forzados.
380+ $ queryParams = array_merge ($ queryParams , $ params );
381+
382+ // Reconstruir la cadena de consulta con los nuevos parámetros.
383+ $ parsedUrl ['query ' ] = http_build_query ($ queryParams );
384+
385+ // Reconstruir y devolver la URL completa.
386+ return (isset ($ parsedUrl ['scheme ' ]) ? "{$ parsedUrl ['scheme ' ]}:// " : '' ) .
387+ (isset ($ parsedUrl ['user ' ]) ? "{$ parsedUrl ['user ' ]}" . (isset ($ parsedUrl ['pass ' ]) ? ": {$ parsedUrl ['pass ' ]}" : '' ) .'@ ' : '' ) .
388+ (isset ($ parsedUrl ['host ' ]) ? "{$ parsedUrl ['host ' ]}" : '' ) .
389+ (isset ($ parsedUrl ['port ' ]) ? ": {$ parsedUrl ['port ' ]}" : '' ) .
390+ (isset ($ parsedUrl ['path ' ]) ? "{$ parsedUrl ['path ' ]}" : '' ) .
391+ (isset ($ parsedUrl ['query ' ]) ? "? {$ parsedUrl ['query ' ]}" : '' ) .
392+ (isset ($ parsedUrl ['fragment ' ]) ? "# {$ parsedUrl ['fragment ' ]}" : '' )
393+ ;
394+ }
395+
338396 /**
339397 * Extrae información detallada sobre un error a partir de la última respuesta HTTP.
340398 *
0 commit comments