pycontribs/jira

Odd behavior of with `remove_watcher` method of JIRA client:

danmanor opened this issue · 2 comments

Bug summary

Hello,

I have encountered odd behavior from remove_watcher method of JIRA client - When I attempt to remove a watcher from an issue that is no longer an active user on Jira, it raises a jira.JIRAError exception. I humbly believe it shouldn't fail in that case, but just remove the watcher.

Thank you

Is there an existing issue for this?

  • I have searched the existing issues

Jira Instance type

Jira Cloud (Hosted by Atlassian)

Jira instance version

No response

jira-python version

3.5.2

Python Interpreter version

3.11.4

Which operating systems have you used?

  • Linux
  • macOS
  • Windows

Reproduction steps

Remove an inactive watcher user from an issue

Stack trace

jira.exceptions.JIRAError: JiraError HTTP None
12:49:47  	text: No matching user found for: <user>

Expected behaviour

Watcher should be removed.

Additional Context

No response

I am not sure what can be done about this. In Jira Cloud the issue/{issueIdOrKey}/watchers endpoint expects an accountId to delete a user. To get the accountId we search for the username on the user/search endpoint. It seems like in this case the endpoint didn't return a user. The only "fix" I could think of would be to add a method that accepts an accountId instead of a username.

in our setup, with jira==3.6.0, I get:

issue_handler/issue_handler_base.py:199: in issue_handling_engine
    self.ticket_key = self.jira_conn.create_ticket(self._create_ticket_fields(), watcher_list)
services/jira.py:131: in create_ticket
    self._connection.add_watcher(ticket.key, watcher)
../jira/client.py:124: in wrapper
    result = func(*arg_list, **kwargs)
../jira/client.py:2326: in add_watcher
    watcher_id = self._get_user_id(watcher)

    def _get_user_id(self, user: str | None) -> str | None:
        """Internal method for translating a user search (str) to an id.
    
        Return None and -1 unchanged.
    
        This function uses :py:meth:`JIRA.search_users` to find the user and then using :py:meth:`JIRA._get_user_identifier` extracts
        the relevant identifier property depending on whether the instance is a Cloud or self-hosted Instance.
    
        Args:
            user (Optional[str]): The search term used for finding a user. None, '-1' and -1 are equivalent to 'Unassigned'.
    
        Raises:
            JIRAError: If any error occurs.
    
        Returns:
            Optional[str]: The Jira user's identifier. Or "-1" and None unchanged.
        """
        if user in (None, -1, "-1"):
            return user
        try:
            user_obj: User
            if self._is_cloud:
                users = self.search_users(query=user, maxResults=20)
            else:
                users = self.search_users(user=user, maxResults=20)
    
            if len(users) < 1:
                raise JIRAError(f"No matching user found for: '{user}'")
    
            matches = []
            if len(users) > 1:
                matches = [u for u in users if self._get_user_identifier(u) == user]
            user_obj = matches[0] if matches else users[0]
    
        except Exception as e:
>           raise JIRAError(str(e))
E           jira.exceptions.JIRAError: JiraError HTTP None
E           	text: JiraError HTTP None
E           	text: No matching user found for: '5eXXXXXXXX'

../jira/client.py:1853: JIRAError

with jira==3.5.2 it works without issue