Skip to content

fix: circuit breaker, estado INACTIVO y fallback SOAP apagado por defecto - #12

Merged
franklinmdev merged 5 commits into
mainfrom
fix/breaker-notfound-and-estado
Sep 23, 2026
Merged

franklinmdev merged 5 commits into
mainfrom
fix/breaker-notfound-and-estado

Conversation

@franklinmdev

Copy link
Copy Markdown
Owner

Qué corrige

  1. Circuit breaker y DgiiNotFoundError. ConsecutiveBreaker contaba un RNC inexistente como fallo. Tras 5 consultas seguidas de RNCs inexistentes, DgiiClient abría el circuito de scraping y toda consulta, incluso de un RNC real, lanzaba AllStrategiesFailedError ("Circuito abierto") por 60 segundos. Ahora DgiiNotFoundError cuenta como éxito para el circuito y se sigue propagando.
  2. estado INACTIVO. parseContribuyenteHtml usaba includes('ACTIVO'), así que un estado INACTIVO salía como ACTIVO. Ahora compara el valor completo normalizado.

Cómo se verificó

  • Tests nuevos escritos primero y vistos fallar (4 rojos), luego verdes.
  • npm run typecheck, npx vitest run --coverage: 313 tests, umbrales de cobertura OK.
  • Repro con fetch simulado contra dist/: antes, las consultas 6 y 7 lanzaban AllStrategiesFailedError; ahora las 7 lanzan DgiiNotFoundError.
  • node scripts/smoke-test.mjs contra la DGII real: 4/4.

Encontrados al preparar el skill para agentes; el skill documentará el comportamiento corregido.

…aker

Un RNC inexistente es una respuesta autoritativa de la DGII, no una
falla del servicio. El breaker lo contaba como fallo: tras 5 consultas
seguidas de RNCs inexistentes, DgiiClient abría el circuito de scraping
y cualquier consulta, incluso de un RNC real, lanzaba
AllStrategiesFailedError durante 60 segundos.

Ahora DgiiNotFoundError cuenta como éxito para el circuito y se sigue
propagando al llamador.
El parser usaba includes('ACTIVO'), así que un estado INACTIVO se
reportaba como ACTIVO. Ahora compara el estado completo, normalizado a
mayúsculas y sin espacios sobrantes.
La DGII responde con un mensaje de campo requerido si falta el código
de seguridad, igual que con el RNC comprador. Verificado en vivo con el
e-NCF E310125217173 el 2026-09-22.
La DGII bloqueó el endpoint SOAP en enero 2025. Con el fallback activo
por defecto, cada falla del scraping costaba una petición inútil, y si
el endpoint respondiera vacío el parser SOAP lo reportaría como
DgiiNotFoundError: una caída se vería como "RNC no registrado".

soapFallback ahora es false por defecto; se puede activar con
soapFallback: true.

BREAKING CHANGE: DgiiClient ya no intenta SOAP a menos que se pase
soapFallback: true.
@franklinmdev franklinmdev changed the title fix: circuit breaker con RNCs inexistentes y estado INACTIVO fix: circuit breaker, estado INACTIVO y fallback SOAP apagado por defecto Sep 23, 2026
@franklinmdev

Copy link
Copy Markdown
Owner Author

Agregado tras el code review: soapFallback pasa a false por defecto (💥). Con SOAP bloqueado, el fallback solo costaba una petición extra y, si el endpoint respondiera vacío, una caída llegaría al usuario como DgiiNotFoundError. Test nuevo no usa el fallback SOAP por defecto (rojo antes, verde ahora); los tests que ejercen SOAP ahora pasan soapFallback: true. 314 tests, cobertura OK, smoke test en vivo OK.

@franklinmdev
franklinmdev merged commit 97bb1ae into main Sep 23, 2026
7 checks passed
@franklinmdev
franklinmdev deleted the fix/breaker-notfound-and-estado branch September 23, 2026 01:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant