# Buggy code
def main():
    module = AnsibleModule(
        argument_spec=dict(
            hostname=dict(type="str", default=os.environ.get("VMWARE_HOST")),
            username=dict(type="str", default=os.environ.get("VMWARE_USER")),
            password=dict(
                type="str", no_log=True, default=os.environ.get("VMWARE_PASSWORD")
            ),
            validate_certs=dict(required=False, type="bool", default=True),
            name=dict(required=False, type="str"),
            name_match=dict(required=False, type="str", default="first"),
            uuid=dict(required=False, type="str"),
            folder=dict(required=False, type="str", default="/vm"),
            datacenter=dict(required=True, type="str"),
        ),
        required_one_of=[["name", "uuid"]],
    )

    # FindByInventoryPath() does not require an absolute path
    # so we should leave the input folder path unmodified
    module.params["folder"] = module.params["folder"].rstrip("/")

    pyv = PyVmomiHelper(module)
    # Check if the VM exists before continuing
    vm = pyv.getvm(
        name=module.params["name"],
        folder=module.params["folder"],
        uuid=module.params["uuid"],
    )

    # VM already exists
    if vm:
        try:
            module.exit_json(instance=pyv.gather_facts(vm))
        except Exception as exc:
            module.fail_json(msg="Fact gather failed with exception %s" % to_text(exc))
    else:
        msg = "Unable to gather facts for non-existing VM "
        if module.params["name"]:
            msg += "%(name)s" % module.params
        elif module.params["uuid"]:
            msg += "%(uuid)s" % module.params
        module.fail_json(msg=msg)


# Traceback (nAttributeError)
{
"_ansible_parsed": false,
"exception": "Traceback (most recent call last):\n  File \"/tmp/ansible_t0MsFQ/ansible_module_vmware_guest.py\", line 1332, in <module>\n    main()\n  File \"/tmp/ansible_t0MsFQ/ansible_module_vmware_guest.py\", line 1291, in main\n    pyv = PyVmomiHelper(module)\n  File \"/tmp/ansible_t0MsFQ/ansible_module_vmware_guest.py\", line 436, in __init__\n    self.content = connect_to_api(self.module)\n  File \"/tmp/ansible_t0MsFQ/ansible_modlib.zip/ansible/module_utils/vmware.py\", line 333, in connect_to_api\n  File \"/var/lib/awx/venv/ansible/lib/python2.7/site-packages/pyVim/connect.py\", line 817, in SmartConnect\n    sslContext)\n  File \"/var/lib/awx/venv/ansible/lib/python2.7/site-packages/pyVim/connect.py\", line 702, in __FindSupportedVersion\n    sslContext)\n  File \"/var/lib/awx/venv/ansible/lib/python2.7/site-packages/pyVim/connect.py\", line 622, in __GetServiceVersionDescription\n    path + \"/vimServiceVersions.xml\", sslContext)\n  File \"/var/lib/awx/venv/ansible/lib/python2.7/site-packages/pyVim/connect.py\", line 588, in __GetElementTree\n    conn.request(\"GET\", path)\n  File \"/usr/lib64/python2.7/httplib.py\", line 1017, in request\n    self._send_request(method, url, body, headers)\n  File \"/usr/lib64/python2.7/httplib.py\", line 1045, in _send_request\n    self.putrequest(method, url, **skips)\n  File \"/usr/lib64/python2.7/httplib.py\", line 946, in putrequest\n    host_enc = self.host.encode(\"ascii\")\nAttributeError: 'NoneType' object has no attribute 'encode'\n",
"_ansible_no_log": false,
"_ansible_delegated_vars": {
"ansible_host": "localhost"
},
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_t0MsFQ/ansible_module_vmware_guest.py\", line 1332, in <module>\n    main()\n  File \"/tmp/ansible_t0MsFQ/ansible_module_vmware_guest.py\", line 1291, in main\n    pyv = PyVmomiHelper(module)\n  File \"/tmp/ansible_t0MsFQ/ansible_module_vmware_guest.py\", line 436, in __init__\n    self.content = connect_to_api(self.module)\n  File \"/tmp/ansible_t0MsFQ/ansible_modlib.zip/ansible/module_utils/vmware.py\", line 333, in connect_to_api\n  File \"/var/lib/awx/venv/ansible/lib/python2.7/site-packages/pyVim/connect.py\", line 817, in SmartConnect\n    sslContext)\n  File \"/var/lib/awx/venv/ansible/lib/python2.7/site-packages/pyVim/connect.py\", line 702, in __FindSupportedVersion\n    sslContext)\n  File \"/var/lib/awx/venv/ansible/lib/python2.7/site-packages/pyVim/connect.py\", line 622, in __GetServiceVersionDescription\n    path + \"/vimServiceVersions.xml\", sslContext)\n  File \"/var/lib/awx/venv/ansible/lib/python2.7/site-packages/pyVim/connect.py\", line 588, in __GetElementTree\n    conn.request(\"GET\", path)\n  File \"/usr/lib64/python2.7/httplib.py\", line 1017, in request\n    self._send_request(method, url, body, headers)\n  File \"/usr/lib64/python2.7/httplib.py\", line 1045, in _send_request\n    self.putrequest(method, url, **skips)\n  File \"/usr/lib64/python2.7/httplib.py\", line 946, in putrequest\n    host_enc = self.host.encode(\"ascii\")\nAttributeError: 'NoneType' object has no attribute 'encode'\n",
"changed": false,
"module_stdout": "",
"failed": true,
"rc": 0,
"msg": "MODULE FAILURE"
}

# Fixed code
def main():
    argument_spec = vmware_argument_spec()
    argument_spec.update(
        name=dict(type="str"),
        name_match=dict(type="str", default="first"),
        uuid=dict(type="str"),
        folder=dict(type="str", default="/vm"),
        datacenter=dict(type="str", required=True),
    )
    module = AnsibleModule(
        argument_spec=argument_spec, required_one_of=[["name", "uuid"]]
    )

    # FindByInventoryPath() does not require an absolute path
    # so we should leave the input folder path unmodified
    module.params["folder"] = module.params["folder"].rstrip("/")

    pyv = PyVmomiHelper(module)
    # Check if the VM exists before continuing
    vm = pyv.getvm(
        name=module.params["name"],
        folder=module.params["folder"],
        uuid=module.params["uuid"],
    )

    # VM already exists
    if vm:
        try:
            module.exit_json(instance=pyv.gather_facts(vm))
        except Exception as exc:
            module.fail_json(msg="Fact gather failed with exception %s" % to_text(exc))
    else:
        msg = "Unable to gather facts for non-existing VM "
        if module.params["name"]:
            msg += "%(name)s" % module.params
        elif module.params["uuid"]:
            msg += "%(uuid)s" % module.params
        module.fail_json(msg=msg)