chore(release): v0.7.16
Durcit la boucle principale de wgsecure-helper : ne capturait que pywintypes.error (pas Exception en général) et ne protégeait pas CloseHandle individuellement dans le nettoyage, si bien qu'une exception inattendue sur une requête pouvait arrêter tout le service — expliquant un premier échange réussi (juste après démarrage) puis un service injoignable ensuite. Gère aussi ERROR_PIPE_CONNECTED (course normale, pas rare, entre CreateNamedPipe et ConnectNamedPipe) au lieu de la traiter comme une erreur. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -1,3 +1,3 @@
|
||||
__version__ = "0.7.15"
|
||||
__version__ = "0.7.16"
|
||||
APP_NAME = "WGSecure"
|
||||
APP_SHORT = "WGS"
|
||||
|
||||
@@ -226,12 +226,12 @@ def _handle_connection(handle, logger: logging.Logger) -> None:
|
||||
except ValidationError as e:
|
||||
resp = {"ok": False, "message": str(e)}
|
||||
logger.info("%s -> ok=%s", cmd, resp.get("ok"))
|
||||
except (pywintypes.error, ValueError, OSError) as e:
|
||||
except Exception as e:
|
||||
logger.exception("Requête invalide ou erreur pipe")
|
||||
resp = {"ok": False, "message": f"Erreur interne : {e}"}
|
||||
try:
|
||||
win32file.WriteFile(handle, (json.dumps(resp) + "\n").encode("utf-8"))
|
||||
except pywintypes.error:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@@ -273,26 +273,57 @@ class WGSecureHelperService(win32serviceutil.ServiceFramework):
|
||||
)
|
||||
logger = _get_logger()
|
||||
logger.info("Service démarré")
|
||||
try:
|
||||
self._serve_forever(logger)
|
||||
except Exception:
|
||||
# Filet de sécurité final : si malgré tout ce qui suit une
|
||||
# exception s'échappe encore, elle laisse au moins une trace
|
||||
# exploitable ici plutôt qu'un service qui disparaît en
|
||||
# silence sans rien dans le log.
|
||||
logger.exception("Arrêt inattendu de la boucle principale")
|
||||
finally:
|
||||
logger.info("Service arrêté")
|
||||
|
||||
def _serve_forever(self, logger: logging.Logger) -> None:
|
||||
# Chaque étape est individuellement protégée et ne peut donc jamais
|
||||
# faire sortir la boucle sur une exception non prévue : un service
|
||||
# censé tourner indéfiniment sans surveillance ne doit jamais
|
||||
# s'arrêter à cause d'un incident sur UNE requête. Une version
|
||||
# antérieure ne capturait que pywintypes.error (pas Exception en
|
||||
# général) et ne protégeait pas CloseHandle individuellement dans
|
||||
# le `finally` : une erreur non prévue là pouvait remonter et
|
||||
# arrêter tout le service — expliquant un premier échange réussi
|
||||
# (juste après le démarrage du service) puis silence total ensuite.
|
||||
ERROR_PIPE_CONNECTED = 535
|
||||
while self._running:
|
||||
handle = None
|
||||
try:
|
||||
handle = _create_pipe_instance()
|
||||
except pywintypes.error:
|
||||
logger.exception("Création du pipe impossible")
|
||||
break
|
||||
try:
|
||||
win32pipe.ConnectNamedPipe(handle, None)
|
||||
try:
|
||||
win32pipe.ConnectNamedPipe(handle, None)
|
||||
except pywintypes.error as e:
|
||||
# Le client s'est connecté entre CreateNamedPipe et
|
||||
# ConnectNamedPipe : cas normal (pas une erreur), pas
|
||||
# rare vu la fréquence des appels — sans ce cas
|
||||
# particulier, la requête était silencieusement ratée
|
||||
# à chaque fois qu'il se produisait.
|
||||
if e.winerror != ERROR_PIPE_CONNECTED:
|
||||
raise
|
||||
if not self._running:
|
||||
break
|
||||
_handle_connection(handle, logger)
|
||||
except pywintypes.error:
|
||||
except Exception:
|
||||
logger.exception("Erreur sur une connexion cliente")
|
||||
finally:
|
||||
try:
|
||||
win32pipe.DisconnectNamedPipe(handle)
|
||||
except pywintypes.error:
|
||||
pass
|
||||
win32file.CloseHandle(handle)
|
||||
logger.info("Service arrêté")
|
||||
if handle:
|
||||
try:
|
||||
win32pipe.DisconnectNamedPipe(handle)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
win32file.CloseHandle(handle)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user