diff --git a/app/integrations/google_workspace/google_directory.py b/app/integrations/google_workspace/google_directory.py index 55b33a80..314e2349 100644 --- a/app/integrations/google_workspace/google_directory.py +++ b/app/integrations/google_workspace/google_directory.py @@ -175,6 +175,7 @@ def list_groups_with_members( members_details: bool = True, groups_filters: list = [], query: str | None = None, + tolerate_errors: bool = False, ): """List all groups in the Google Workspace domain with their members. @@ -183,6 +184,7 @@ def list_groups_with_members( members_details (bool): Include the members details in the response. groups_filters (list): List of filters to apply to the groups. query (str): The query to search for groups. + tolerate_errors (bool): Whether to include groups that encountered errors during member detail retrieval. Returns: list: A list of group objects with members. Any group without members will not be included. @@ -210,19 +212,25 @@ def list_groups_with_members( except Exception as e: logger.warning(f"Error getting members for group {group['email']}: {e}") continue + if members and members_details: detailed_members = [] - try: - for member in members: + error_occurred = False + for member in members: + try: logger.info(f"Getting user details for member: {member['email']}") detailed_members.append( get_user(member["email"], fields="name, primaryEmail") ) - group["members"] = detailed_members - groups_with_members.append(group) - except Exception as e: - logger.warning( - f"Error getting user details for group {member['email']}: {e}" - ) + except Exception as e: + logger.warning( + f"Error getting user details for member {member['email']}: {e}" + ) + error_occurred = True + if not tolerate_errors: + break + if error_occurred and not tolerate_errors: continue + group["members"] = detailed_members + groups_with_members.append(group) return groups_with_members diff --git a/app/tests/integrations/google_workspace/test_google_directory.py b/app/tests/integrations/google_workspace/test_google_directory.py index cd413e1b..e483a28c 100644 --- a/app/tests/integrations/google_workspace/test_google_directory.py +++ b/app/tests/integrations/google_workspace/test_google_directory.py @@ -403,7 +403,7 @@ def test_list_groups_with_members_error_in_list_group_members( google_groups, google_group_members, google_users, - google_groups_w_users + google_groups_w_users, ): groups = google_groups(2) group_members = [Exception("Error fetching group members"), google_group_members(2)] @@ -487,6 +487,40 @@ def test_list_groups_with_members_error_in_get_user( assert google_directory.list_groups_with_members() == [] +@patch("integrations.google_workspace.google_directory.list_groups") +@patch("integrations.google_workspace.google_directory.list_group_members") +@patch("integrations.google_workspace.google_directory.get_user") +def test_list_groups_with_members_tolerate_errors( + mock_get_user, + mock_list_group_members, + mock_list_groups, + google_groups, + google_group_members, + google_users, +): + groups = google_groups(2) + group_members = [google_group_members(2), google_group_members(2)] + users = [ + Exception("Error fetching user details"), + google_users(1)[0], + Exception("Error fetching user details"), + google_users(1)[0], + ] + + mock_list_groups.return_value = groups + mock_list_group_members.side_effect = group_members + mock_get_user.side_effect = users + + # Expected result should include both groups, with the second group having one member + expected_groups_with_users = [groups[0], groups[1]] + expected_groups_with_users[0]["members"] = [] + expected_groups_with_users[1]["members"] = [google_users(1)[0]] + + result = google_directory.list_groups_with_members(tolerate_errors=True) + + assert result == expected_groups_with_users + + @patch("integrations.google_workspace.google_directory.list_groups") def test_list_groups_with_members_skips_when_no_groups(mock_list_groups): mock_list_groups.return_value = []