# Buggy code
def main():
    argument_spec = dict(
        assets=dict(required=False),
        files=dict(required=False, default=[], type="list"),
        prevent=dict(required=False, default=[], type="list"),
        password_management=dict(
            required=False, default="default", choices=["default", "random"]
        ),
    )

    module = TowerModule(argument_spec=argument_spec, supports_check_mode=False)

    if not HAS_TOWER_CLI:
        module.fail_json(msg="ansible-tower-cli required for this module")

    if not TOWER_CLI_HAS_EXPORT:
        module.fail_json(msg="ansible-tower-cli version does not support export")

    assets = module.params.get("assets")
    prevent = module.params.get("prevent")
    password_management = module.params.get("password_management")
    files = module.params.get("files")

    result = dict(
        changed=False,
        msg="",
        output="",
    )

    if not assets and not files:
        result["msg"] = "Assets or files must be specified"
        module.fail_json(**result)

    path = None
    if assets:
        # We got assets so we need to dump this out to a temp file and append that to files
        handle, path = mkstemp(prefix="", suffix="", dir="")
        with open(path, "w") as f:
            f.write(assets)
        files.append(path)

    tower_auth = tower_auth_config(module)
    failed = False
    with settings.runtime_values(**tower_auth):
        try:
            sender = Sender(no_color=False)
            old_stdout = sys.stdout
            sys.stdout = captured_stdout = StringIO()
            try:
                sender.send(files, prevent, password_management)
            except TypeError as e:
                # Newer versions of TowerCLI require 4 parameters
                sender.send(files, prevent, [], password_management)

            if sender.error_messages > 0:
                failed = True
                result["msg"] = "Transfer Failed with %d errors" % sender.error_messages
            if sender.changed_messages > 0:
                result["changed"] = True
        except TowerCLIError as e:
            result["msg"] = e
            failed = True
        finally:
            if path is not None:
                os.remove(path)
            result["output"] = captured_stdout.getvalue().split("\n")
            sys.stdout = old_stdout

    # Return stdout so that module returns will work
    if failed:
        module.fail_json(**result)
    else:
        module.exit_json(**result)


# 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(
        assets=dict(required=False),
        files=dict(required=False, default=[], type="list"),
        prevent=dict(required=False, default=[], type="list"),
        password_management=dict(
            required=False, default="default", choices=["default", "random"]
        ),
    )

    module = TowerModule(argument_spec=argument_spec, supports_check_mode=False)

    if not HAS_TOWER_CLI:
        module.fail_json(msg="ansible-tower-cli required for this module")

    if not TOWER_CLI_HAS_EXPORT:
        module.fail_json(msg="ansible-tower-cli version does not support export")

    assets = module.params.get("assets")
    prevent = module.params.get("prevent")
    password_management = module.params.get("password_management")
    files = module.params.get("files")

    result = dict(
        changed=False,
        msg="",
        output="",
    )

    if not assets and not files:
        result["msg"] = "Assets or files must be specified"
        module.fail_json(**result)

    path = None
    if assets:
        # We got assets so we need to dump this out to a temp file and append that to files
        handle, path = mkstemp(prefix="", suffix="", dir="")
        with open(path, "w") as f:
            f.write(assets)
        files.append(path)

    tower_auth = tower_auth_config(module)
    failed = False
    with settings.runtime_values(**tower_auth):
        try:
            sender = Sender(no_color=False)
            old_stdout = sys.stdout
            sys.stdout = captured_stdout = StringIO()
            try:
                sender.send(files, prevent, password_management)
            except TypeError as e:
                # Newer versions of TowerCLI require 4 parameters
                sender.send(files, prevent, [], password_management)

            if sender.error_messages > 0:
                failed = True
                result["msg"] = "Transfer Failed with %d errors" % sender.error_messages
            if sender.changed_messages > 0:
                result["changed"] = True
        except TowerCLIError as e:
            result["msg"] = e.message
            failed = True
        finally:
            if path is not None:
                os.remove(path)
            result["output"] = captured_stdout.getvalue().split("\n")
            sys.stdout = old_stdout

    # Return stdout so that module returns will work
    if failed:
        module.fail_json(**result)
    else:
        module.exit_json(**result)