Skip to content

Commit 850b170

Browse files
FIX: Se maneja de manera general las excepciones al problema de conexión sin respuesta
1 parent 724b31c commit 850b170

1 file changed

Lines changed: 63 additions & 7 deletions

File tree

src/ApiClient.php

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -383,23 +383,46 @@ public function consume(
383383
$options[\GuzzleHttp\RequestOptions::JSON] = $data;
384384
}
385385

386+
// realizar consulta HTTP con reintento por si falla la sesión del SII.
387+
foreach ([true, false] as $auth_cache) {
388+
389+
// Forzar el valor de auth_cache en la llamada a la API.
390+
$this->last_url = $this->forceUrlParams($this->last_url, [
391+
'auth_cache' => (int)$auth_cache,
392+
]);
393+
386394
// Ejecutar consulta al SII.
387395
try {
388396
$this->last_response = $client->request(
389397
method: $method,
390398
uri: $this->last_url,
391399
options: $options
392400
);
393-
} catch (\GuzzleHttp\Exception\RequestException $e) {
394-
if ($e->hasResponse()) {
401+
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
402+
// Obtener la respuesta de la llamada.
395403
$this->last_response = $e->getResponse();
404+
405+
// Si es un error HTTP 401 con problema de sesión pasamos a la otra iteración
406+
// del ciclo foreach para reintentar sin caché de sesión del SII.
407+
if ($this->getLastResponse()->getStatusCode() == 401) {
408+
if ($this->getLastResponse()->getHeaderLine('X-Stats-NavegadorSessionProblem')) {
409+
continue;
410+
}
411+
}
412+
413+
// Si no es un error 401 con problema de sesión se lanza la excepción.
414+
$this->throwException();
415+
} catch (\GuzzleHttp\Exception\GuzzleException $e) {
416+
throw new ApiException('Error de conexión con el SII: ' . $e->getMessage(), 500);
417+
}
418+
419+
// Break obligatorio, ya que si la llamada es exitosa no se debe reintentar.
420+
if ($this->getLastResponse()->getStatusCode() == 200) {
421+
break;
396422
}
423+
424+
// Si no se reintentó se lanza excepción por no ser código 200 (break anterior).
397425
$this->throwException();
398-
} catch (\GuzzleHttp\Exception\ConnectException $e) {
399-
throw new ApiException(
400-
message: 'Error de conexión con el SII: ' . $e->getMessage(),
401-
code: 500
402-
);
403426
}
404427

405428
// Entregar respuesta (contenida en el mismo objeto del cliente).
@@ -468,4 +491,37 @@ private function env(string $name)
468491
{
469492
return function_exists('env') ? env($name) : getenv($name);
470493
}
494+
495+
/**
496+
* Fuerza parámetros específicos en la URL dada.
497+
*
498+
* @param string $url La URL original a modificar.
499+
* @param array $params Arreglo asociativo de parámetros para añadir a la URL.
500+
* @return string La URL modificada con los nuevos parámetros.
501+
*/
502+
private function forceUrlParams(string $url, array $params): string
503+
{
504+
// Parsear la URL para extraer componentes.
505+
$parsedUrl = parse_url($url);
506+
507+
// Parsear la cadena de consulta existente y obtener los parámetros actuales.
508+
parse_str($parsedUrl['query'] ?? '', $queryParams);
509+
510+
// Fusionar los parámetros existentes con los nuevos parámetros forzados.
511+
$queryParams = array_merge($queryParams, $params);
512+
513+
// Reconstruir la cadena de consulta con los nuevos parámetros.
514+
$parsedUrl['query'] = http_build_query($queryParams);
515+
516+
// Reconstruir y devolver la URL completa.
517+
return (isset($parsedUrl['scheme']) ? "{$parsedUrl['scheme']}://" : '') .
518+
(isset($parsedUrl['user']) ? "{$parsedUrl['user']}" . (isset($parsedUrl['pass']) ? ":{$parsedUrl['pass']}" : '') .'@' : '') .
519+
(isset($parsedUrl['host']) ? "{$parsedUrl['host']}" : '') .
520+
(isset($parsedUrl['port']) ? ":{$parsedUrl['port']}" : '') .
521+
(isset($parsedUrl['path']) ? "{$parsedUrl['path']}" : '') .
522+
(isset($parsedUrl['query']) ? "?{$parsedUrl['query']}" : '') .
523+
(isset($parsedUrl['fragment']) ? "#{$parsedUrl['fragment']}" : '')
524+
;
525+
}
526+
471527
}

0 commit comments

Comments
 (0)