# Buggy code
def main():
    argument_spec = dict(
        job_id=dict(type="int", required=True),
        timeout=dict(type="int"),
        min_interval=dict(type="float", default=1),
        max_interval=dict(type="float", default=30),
    )

    module = TowerModule(argument_spec, supports_check_mode=True)

    json_output = {}
    fail_json = None

    tower_auth = tower_auth_config(module)
    with settings.runtime_values(**tower_auth):
        tower_check_mode(module)
        job = tower_cli.get_resource("job")
        params = module.params.copy()

        # tower-cli gets very noisy when monitoring.
        # We pass in our our outfile to suppress the out during our monitor call.
        outfile = StringIO()
        params["outfile"] = outfile

        job_id = params.get("job_id")
        try:
            result = job.monitor(job_id, **params)
        except exc.Timeout as excinfo:
            result = job.status(job_id)
            result["id"] = job_id
            json_output["msg"] = "Timeout waiting for job to finish."
            json_output["timeout"] = True
        except exc.NotFound as excinfo:
            fail_json = dict(
                msg="Unable to wait, no job_id {0} found: {1}".format(job_id, excinfo),
                changed=False,
            )
        except (exc.ConnectionError, exc.BadRequest) as excinfo:
            fail_json = dict(
                msg="Unable to wait for job: {0}".format(excinfo), changed=False
            )

    if fail_json is not None:
        module.fail_json(**fail_json)

    json_output["success"] = True
    for k in ("id", "status", "elapsed", "started", "finished"):
        json_output[k] = result.get(k)

    module.exit_json(**json_output)


# Traceback (tower_cli.exceptions.AuthError)
TASK [Set AWX admin account] *******************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: tower_cli.exceptions.AuthError: Invalid Tower authentication credentials (HTTP 401).
fatal: [awx1]: FAILED! => changed=false
module_stderr: |-
Traceback (most recent call last):
File "/home/d069683/.ansible/tmp/ansible-tmp-1546595798.81-18639309082017/AnsiballZ_tower_user.py", line 113, in <module>
_ansiballz_main()
File "/home/d069683/.ansible/tmp/ansible-tmp-1546595798.81-18639309082017/AnsiballZ_tower_user.py", line 105, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/d069683/.ansible/tmp/ansible-tmp-1546595798.81-18639309082017/AnsiballZ_tower_user.py", line 48, in invoke_module
imp.load_module('__main__', mod, module, MOD_DESC)
File "/tmp/ansible_tower_user_payload_uMnpMh/__main__.py", line 131, in <module>
File "/tmp/ansible_tower_user_payload_uMnpMh/__main__.py", line 118, in main
File "/usr/local/lib/python2.7/dist-packages/tower_cli/models/base.py", line 698, in modify
return self.write(pk, create_on_missing=create_on_missing, force_on_exists=True, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tower_cli/models/base.py", line 361, in write
**kwargs
File "/usr/local/lib/python2.7/dist-packages/tower_cli/models/base.py", line 223, in _lookup
existing_data = self.get(include_debug_header=include_debug_header, **read_params)
File "/usr/local/lib/python2.7/dist-packages/tower_cli/models/base.py", line 486, in get
response = self.read(pk=pk, fail_on_no_results=True, fail_on_multiple_results=True, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tower_cli/models/base.py", line 288, in read
r = client.get(url, params=kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 521, in get
return self.request('GET', url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tower_cli/api.py", line 255, in request
raise exc.AuthError('Invalid Tower authentication credentials (HTTP 401).')
tower_cli.exceptions.AuthError: Invalid Tower authentication credentials (HTTP 401).
module_stdout: ''
msg: |-
MODULE FAILURE
See stdout/stderr for the exact error
rc: 1

# Fixed code
def main():
    argument_spec = dict(
        job_id=dict(type="int", required=True),
        timeout=dict(type="int"),
        min_interval=dict(type="float", default=1),
        max_interval=dict(type="float", default=30),
    )

    module = TowerModule(argument_spec, supports_check_mode=True)

    json_output = {}
    fail_json = None

    tower_auth = tower_auth_config(module)
    with settings.runtime_values(**tower_auth):
        tower_check_mode(module)
        job = tower_cli.get_resource("job")
        params = module.params.copy()

        # tower-cli gets very noisy when monitoring.
        # We pass in our our outfile to suppress the out during our monitor call.
        outfile = StringIO()
        params["outfile"] = outfile

        job_id = params.get("job_id")
        try:
            result = job.monitor(job_id, **params)
        except exc.Timeout as excinfo:
            result = job.status(job_id)
            result["id"] = job_id
            json_output["msg"] = "Timeout waiting for job to finish."
            json_output["timeout"] = True
        except exc.NotFound as excinfo:
            fail_json = dict(
                msg="Unable to wait, no job_id {0} found: {1}".format(job_id, excinfo),
                changed=False,
            )
        except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo:
            fail_json = dict(
                msg="Unable to wait for job: {0}".format(excinfo), changed=False
            )

    if fail_json is not None:
        module.fail_json(**fail_json)

    json_output["success"] = True
    for k in ("id", "status", "elapsed", "started", "finished"):
        json_output[k] = result.get(k)

    module.exit_json(**json_output)