From d505fecfdb86e31130b25369d29b37ea3a66a67c Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:22:08 -0500 Subject: [PATCH 1/3] fix: catch ValidationError instead of SchemaError for message validation SchemaError is raised when the schema itself is malformed, not when data fails validation against it. The correct exception for failed validation is ValidationError. With SchemaError, actual validation failures propagated as unhandled exceptions. Affected two locations: message_validate() (line 552) and the user messages validation in run() (line 1838). Co-Authored-By: Claude Opus 4.6 (1M context) --- roadblock.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roadblock.py b/roadblock.py index fe88414..6244d7e 100644 --- a/roadblock.py +++ b/roadblock.py @@ -549,7 +549,7 @@ def message_validate(self, message): jsonschema.validate(instance=message, schema=self.schema) logger.debug("message passed schema validation [%s]", self.message_to_str(message)) - except jsonschema.exceptions.SchemaError: + except jsonschema.exceptions.ValidationError: logger.error("message failed schema validation [%s]", self.message_to_str(message)) return False @@ -1835,7 +1835,7 @@ def run_it(self): try: jsonschema.validate(instance=self.user_messages, schema=self.user_schema) - except jsonschema.exceptions.SchemaError as exception: + except jsonschema.exceptions.ValidationError as exception: logger.critical(exception) logger.critical("Could not JSON validate the user messages!") return self.RC_INVALID_INPUT From 0b94de9abadb21d209c259459eb68ec7da3f5a0e Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:22:51 -0500 Subject: [PATCH 2/3] fix: add backoff on redis connection/timeout errors in stream_add MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ConnectionError or TimeoutError, ret_val stayed at its initial value of 0. The backoff check (ret_val is None) didn't match, so the success log fired incorrectly and the while loop retried immediately with no delay — a tight busy-loop on persistent connection failures. Set ret_val = None in both exception handlers so the existing backoff logic kicks in. Co-Authored-By: Claude Opus 4.6 (1M context) --- roadblock.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roadblock.py b/roadblock.py index 6244d7e..fc4cd89 100644 --- a/roadblock.py +++ b/roadblock.py @@ -1237,9 +1237,11 @@ def stream_add(self, stream_name, message): except redis.exceptions.ConnectionError as con_error: logger.error("%s", con_error) logger.error("Stream add to '%s' failed due to connection error!", stream_name) + ret_val = None except redis.exceptions.TimeoutError as con_error: logger.error("%s", con_error) logger.error("Stream add to '%s' failed due to a timeout error!", stream_name) + ret_val = None if ret_val is None: logger.warning("Failed attempt %d to add message '%s' to stream '%s'", counter, message, stream_name) From 832db54804c6f568009880166bf8b18c8f1d0f6c Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:24:20 -0500 Subject: [PATCH 3/3] fix: remove duplicate recipient check in message_for_me Line 574 checked `not "recipient" in message["payload"]` identically to line 568. The check was already true by that point in the elif chain, so this branch was unreachable. Co-Authored-By: Claude Opus 4.6 (1M context) --- roadblock.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/roadblock.py b/roadblock.py index fc4cd89..fa77c8a 100644 --- a/roadblock.py +++ b/roadblock.py @@ -571,8 +571,6 @@ def message_for_me(self, message): incomplete_message = True elif not "id" in message["payload"]["sender"]: incomplete_message = True - elif not "recipient" in message["payload"]: - incomplete_message = True elif not "type" in message["payload"]["recipient"]: incomplete_message = True