Skip to content

Commit 52d0902

Browse files
committed
Se agrega reitento automático sin uso de caché de sesión (para forzar nueva sesión) cuando la sesión de SII es reportada con problema por API Gateway.
1 parent 6d02232 commit 52d0902

1 file changed

Lines changed: 66 additions & 8 deletions

File tree

src/ApiClient.php

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)