# Buggy code
def decryptPassword(cryptPass):
    hsm = _get_hsm()
    try:
        ret = hsm.decrypt_password(cryptPass)
    except Exception as exx:  # pragma: no cover
        log.warning(exx)
        ret = FAILED_TO_DECRYPT_PASSWORD
    return ret


# Traceback (UnicodeDecodeError)
[2018-08-14 14:49:53,123] ERROR in app: Exception on /system/documentation [GET]
Traceback (most recent call last):
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/fred/privacyidea/privacyidea/privacyidea/api/lib/prepolicy.py", line 120, in policy_wrapper
return wrapped_function(*args, **kwds)
File "/home/fred/privacyidea/privacyidea/privacyidea/api/auth.py", line 316, in decorated_function
return f(*args, **kwargs)
File "/home/fred/privacyidea/privacyidea/privacyidea/api/system.py", line 113, in get_config_documentation
context=context))
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/templating.py", line 135, in render_template
context, ctx.app)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/templating.py", line 117, in _render
rv = template.render(context)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/fred/privacyidea/privacyidea/privacyidea/static/templates/documentation.rst", line 56, in top-level template code
{{k}}: **{{v}}**
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 8: ordinal not in range(128)

# Fixed code
def decryptPassword(cryptPass, convert_unicode=False):
    """
    Decrypt the encrypted password ``cryptPass`` and return it.
    If an error occurs during decryption, return FAILED_TO_DECRYPT_PASSWORD.

    :param cryptPass: bytestring
    :param convert_unicode: If true, interpret the decrypted password as an UTF-8 string
                            and convert it to unicode. If an error occurs here,
                            the original bytestring is returned.
    """
    # NOTE: Why do we have the ``convert_unicode`` parameter?
    # Up until now, this always returned bytestrings. However, this breaks
    # LDAP and SQL resolvers, which expect this to return an unicode string
    # (and this makes more sense, because ``encryptPassword`` also
    # takes unicode strings!). But always returning unicode might break
    # other call sites of ``decryptPassword``. So we add the
    # keyword argument to avoid breaking compatibility.
    from privacyidea.lib.utils import to_unicode

    hsm = _get_hsm()
    try:
        ret = hsm.decrypt_password(cryptPass)
    except Exception as exx:  # pragma: no cover
        log.warning(exx)
        ret = FAILED_TO_DECRYPT_PASSWORD
    try:
        if convert_unicode:
            ret = to_unicode(ret)
    except Exception as exx:  # pragma: no cover
        log.warning(exx)
        # just keep ``ret`` as a bytestring in that case
    return ret