# Buggy code
def load_configuration(
    module, candidate=None, action="merge", rollback=None, format="xml"
):
    if all((candidate is None, rollback is None)):
        module.fail_json(msg="one of candidate or rollback must be specified")

    elif all((candidate is not None, rollback is not None)):
        module.fail_json(msg="candidate and rollback are mutually exclusive")

    if format not in FORMATS:
        module.fail_json(msg="invalid format specified")

    if format == "json" and action not in JSON_ACTIONS:
        module.fail_json(msg="invalid action for format json")
    elif format in ("text", "xml") and action not in ACTIONS:
        module.fail_json(msg="invalid action format %s" % format)
    if action == "set" and not format == "text":
        module.fail_json(msg="format must be text when action is set")

    if rollback is not None:
        _validate_rollback_id(module, rollback)
        xattrs = {"rollback": str(rollback)}
    else:
        xattrs = {"action": action, "format": format}

    obj = Element("load-configuration", xattrs)

    if candidate is not None:
        lookup = {
            "xml": "configuration",
            "text": "configuration-text",
            "set": "configuration-set",
            "json": "configuration-json",
        }

        if action == "set":
            cfg = SubElement(obj, "configuration-set")
        else:
            cfg = SubElement(obj, lookup[format])

        if isinstance(candidate, string_types):
            if format == "xml":
                cfg.append(fromstring(candidate))
            else:
                cfg.text = candidate
        else:
            cfg.append(candidate)
    return send_request(module, obj)


# Traceback (UnicodeEncodeError)
(ansible-git)[cns04.sea3:/home/users/cody.john/virtualenv/ansible-git/playbook/deploy]$ ansible-playbook junos_config_test.yml -i inventory --limit cor-001a.sea0.service-now.com --check --diff -vvvv
Using /home/users/cody.john/virtualenv/ansible-git/playbook/deploy/ansible.cfg as config file
Loading callback plugin default of type stdout, v2.0 from /home/users/cody.john/virtualenv/ansible-git/ansible/lib/ansible/plugins/callback/__init__.pyc
Loading callback plugin slack of type notification, v2.0 from /home/users/cody.john/virtualenv/ansible-git/ansible/lib/ansible/plugins/callback/__init__.pyc
[WARNING]: The `prettytable` python module is not installed. Disabling the Slack callback plugin.

[WARNING]: Slack Webhook URL was not provided. The Slack Webhook URL can be provided using the `SLACK_WEBHOOK_URL` environment variable.


PLAYBOOK: junos_config_test.yml *************************************************************************************************************
1 plays in junos_config_test.yml

PLAY [Test junos_config module] *************************************************************************************************************
META: ran handlers

TASK [junos_config ACL test] ****************************************************************************************************************
task path: /home/users/cody.john/virtualenv/ansible-git/playbook/deploy/junos_config_test.yml:13
<cor-001a.sea0.service-now.com> using connection plugin netconf
<cor-001a.sea0.service-now.com> socket_path: /home/users/cody.john/.ansible/pc/a647017206
Using module file /home/users/cody.john/virtualenv/ansible-git/ansible/lib/ansible/modules/network/junos/junos_config.py
<cor-001a.sea0.service-now.com> ESTABLISH LOCAL CONNECTION FOR USER: cody.john
<cor-001a.sea0.service-now.com> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<cor-001a.sea0.service-now.com> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/users/cody.john/.ansible/tmp/ansible-tmp-1491414351.75-223916974745349 `" &amp;&amp; echo ansible-tmp-1491414351.75-223916974745349="` echo /home/users/cody.john/.ansible/tmp/ansible-tmp-1491414351.75-223916974745349 `" ) &amp;&amp; sleep 0'
<cor-001a.sea0.service-now.com> PUT /tmp/tmpUR5ngx TO /home/users/cody.john/.ansible/tmp/ansible-tmp-1491414351.75-223916974745349/junos_config.py
<cor-001a.sea0.service-now.com> EXEC /bin/sh -c 'chmod u+x /home/users/cody.john/.ansible/tmp/ansible-tmp-1491414351.75-223916974745349/ /home/users/cody.john/.ansible/tmp/ansible-tmp-1491414351.75-223916974745349/junos_config.py &amp;&amp; sleep 0'
<cor-001a.sea0.service-now.com> EXEC /bin/sh -c '/glide/bin/python27 /home/users/cody.john/.ansible/tmp/ansible-tmp-1491414351.75-223916974745349/junos_config.py; rm -rf "/home/users/cody.john/.ansible/tmp/ansible-tmp-1491414351.75-223916974745349/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_R2QaH_/ansible_module_junos_config.py", line 341, in <module>
main()
File "/tmp/ansible_R2QaH_/ansible_module_junos_config.py", line 316, in main
result['__backup__'] = str(match.text).strip()
UnicodeEncodeError: 'ascii' codec can't encode characters in position 76583-76585: ordinal not in range(128)

fatal: [cor-001a.sea0.service-now.com]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_R2QaH_/ansible_module_junos_config.py\", line 341, in <module>\n    main()\n  File \"/tmp/ansible_R2QaH_/ansible_module_junos_config.py\", line 316, in main\n    result['__backup__'] = str(match.text).strip()\nUnicodeEncodeError: 'ascii' codec can't encode characters in position 76583-76585: ordinal not in range(128)\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 0
}
to retry, use: --limit @/home/users/cody.john/virtualenv/ansible-git/playbook/deploy/junos_config_test.retry

PLAY RECAP **********************************************************************************************************************************
cor-001a.sea0.service-now.com : ok=0    changed=0    unreachable=0    failed=1

(ansible-git)[cns04.sea3:/home/users/cody.john/virtualenv/ansible-git/playbook/deploy]$

# Fixed code
def load_configuration(
    module, candidate=None, action="merge", rollback=None, format="xml"
):
    if all((candidate is None, rollback is None)):
        module.fail_json(msg="one of candidate or rollback must be specified")

    elif all((candidate is not None, rollback is not None)):
        module.fail_json(msg="candidate and rollback are mutually exclusive")

    if format not in FORMATS:
        module.fail_json(msg="invalid format specified")

    if format == "json" and action not in JSON_ACTIONS:
        module.fail_json(msg="invalid action for format json")
    elif format in ("text", "xml") and action not in ACTIONS:
        module.fail_json(msg="invalid action format %s" % format)
    if action == "set" and not format == "text":
        module.fail_json(msg="format must be text when action is set")

    if rollback is not None:
        _validate_rollback_id(module, rollback)
        xattrs = {"rollback": str(rollback)}
    else:
        xattrs = {"action": action, "format": format}

    obj = Element("load-configuration", xattrs)

    if candidate is not None:
        lookup = {
            "xml": "configuration",
            "text": "configuration-text",
            "set": "configuration-set",
            "json": "configuration-json",
        }

        if action == "set":
            cfg = SubElement(obj, "configuration-set")
        else:
            cfg = SubElement(obj, lookup[format])

        if isinstance(candidate, string_types):
            if format == "xml":
                cfg.append(fromstring(candidate))
            else:
                cfg.text = to_text(candidate, encoding="latin1")
        else:
            cfg.append(candidate)
    return send_request(module, obj)