From 2e9f65fdd630e2be95b57cf30ea748fcfe6c4ec3 Mon Sep 17 00:00:00 2001 From: Ryan Waldheim Date: Thu, 25 Jun 2026 16:47:10 -0700 Subject: [PATCH 1/3] Catch RuntimeError when repo does not exist --- modules/coactd.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/coactd.py b/modules/coactd.py index 53aedad..a6bfa13 100644 --- a/modules/coactd.py +++ b/modules/coactd.py @@ -600,6 +600,8 @@ def do_new_repo( # Ensure principal is in the leaders list if principal not in repo_leaders: repo_leaders.append(principal) + except RuntimeError as e: + self.logger.info(f"Repo {facility}:{repo} not found in database, creating new with principal only") except Exception as e: # Query failed due to other error - do not proceed error_msg = f"Failed to query existing repo data for {facility}:{repo}: {e}" From 8751b2ad7471143a448799e49214cc432cd4fc6b Mon Sep 17 00:00:00 2001 From: Ryan Waldheim Date: Thu, 25 Jun 2026 16:55:06 -0700 Subject: [PATCH 2/3] fix unit tests (unrelated) --- tests/test_slurm_node_memory.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_slurm_node_memory.py b/tests/test_slurm_node_memory.py index 1946f22..947be56 100644 --- a/tests/test_slurm_node_memory.py +++ b/tests/test_slurm_node_memory.py @@ -28,29 +28,29 @@ def test_parse_slurm_nodelist_single(self): def test_parse_slurm_nodelist_range(self): """Test parsing a SLURM node range.""" result = self.importer.parse_slurm_nodelist("sdfmilan[269-272]") - expected = ["sdfmilan0269", "sdfmilan0270", "sdfmilan0271", "sdfmilan0272"] + expected = ["sdfmilan269", "sdfmilan270", "sdfmilan271", "sdfmilan272"] assert result == expected def test_parse_slurm_nodelist_list(self): """Test parsing a comma-separated list of nodes.""" result = self.importer.parse_slurm_nodelist("sdfmilan[006,011,027]") - expected = ["sdfmilan0006", "sdfmilan0011", "sdfmilan0027"] + expected = ["sdfmilan006", "sdfmilan011", "sdfmilan027"] assert result == expected def test_parse_slurm_nodelist_mixed(self): """Test parsing a mixed range and list.""" result = self.importer.parse_slurm_nodelist("sdfmilan[001-003,010,020-022]") expected = [ - "sdfmilan0001", "sdfmilan0002", "sdfmilan0003", - "sdfmilan0010", - "sdfmilan0020", "sdfmilan0021", "sdfmilan0022" + "sdfmilan001", "sdfmilan002", "sdfmilan003", + "sdfmilan010", + "sdfmilan020", "sdfmilan021", "sdfmilan022" ] assert result == expected def test_parse_slurm_nodelist_different_prefix(self): """Test parsing with different node prefix.""" result = self.importer.parse_slurm_nodelist("sdfrome[001-003]") - expected = ["sdfrome0001", "sdfrome0002", "sdfrome0003"] + expected = ["sdfrome001", "sdfrome002", "sdfrome003"] assert result == expected def test_parse_slurm_nodelist_unparseable(self): From e9e630d16e4f7dae46295bb0e75873ac44cf595d Mon Sep 17 00:00:00 2001 From: Ryan Waldheim Date: Thu, 25 Jun 2026 17:08:19 -0700 Subject: [PATCH 3/3] catch on error text - graphql does not propogate Python errors --- modules/coactd.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/modules/coactd.py b/modules/coactd.py index a6bfa13..5fb5dcd 100644 --- a/modules/coactd.py +++ b/modules/coactd.py @@ -600,17 +600,22 @@ def do_new_repo( # Ensure principal is in the leaders list if principal not in repo_leaders: repo_leaders.append(principal) - except RuntimeError as e: - self.logger.info(f"Repo {facility}:{repo} not found in database, creating new with principal only") except Exception as e: - # Query failed due to other error - do not proceed - error_msg = f"Failed to query existing repo data for {facility}:{repo}: {e}" - self.logger.error(error_msg) - raise RuntimeError( - f"Cannot safely proceed with NewRepo: database query failed. " - f"Proceeding with defaults could overwrite existing users/leaders. " - f"Original error: {e}" - ) from e + # Check if this is the specific "repo does not exist" message from API + error_str = str(e) + if "does not exist" in error_str: + # This is the repo-not-found case - treat as normal + self.logger.info(f"Repo {facility}:{repo} not found in database, creating new with principal only") + # Fall through with defaults: repo_users = [principal], repo_leaders = [principal] + else: + # Query failed due to other error - do not proceed + error_msg = f"Failed to query existing repo data for {facility}:{repo}: {e}" + self.logger.error(error_msg) + raise RuntimeError( + f"Cannot safely proceed with NewRepo: database query failed. " + f"Proceeding with defaults could overwrite existing users/leaders. " + f"Original error: {e}" + ) from e # run the facility tasks for this repo self.run_playbook(