# Buggy code
def wrap_tmpl_func(render_str):
    def render_tmpl(
        tmplsrc, from_str=False, to_str=False, context=None, tmplpath=None, **kws
    ):
        if context is None:
            context = {}
        # We want explicit context to overwrite the **kws
        kws.update(context)
        context = kws
        assert "opts" in context
        assert "env" in context

        if isinstance(tmplsrc, basestring):
            if from_str:
                tmplstr = tmplsrc
            else:
                try:
                    with codecs.open(tmplsrc, "r", SLS_ENCODING) as _tmplsrc:
                        tmplstr = _tmplsrc.read()
                except (UnicodeDecodeError, ValueError) as exc:
                    if salt.utils.is_bin_file(tmplsrc):
                        # Template is a bin file, return the raw file
                        with open(tmplsrc, "r") as fp_:
                            return dict(result=True, data=fp_.read())
                    log.error(
                        "Exception ocurred while reading file {0}: {1}".format(
                            tmplsrc, exc
                        )
                    )
                    raise exc
        else:  # assume tmplsrc is file-like.
            tmplstr = tmplsrc.read()
            tmplsrc.close()
        try:
            output = render_str(tmplstr, context, tmplpath)
            if salt.utils.is_windows():
                # Write out with Windows newlines
                output = os.linesep.join(output.splitlines())

        except SaltTemplateRenderError as exc:
            return dict(result=False, data=str(exc))
        except Exception:
            return dict(result=False, data=traceback.format_exc())
        else:
            if to_str:  # then render as string
                return dict(result=True, data=output)
            with tempfile.NamedTemporaryFile("wb", delete=False) as outf:
                outf.write(SLS_ENCODER(output)[0])
                # Note: If nothing is replaced or added by the rendering
                #       function, then the contents of the output file will
                #       be exactly the same as the input.
            return dict(result=True, data=outf.name)

    render_tmpl.render_str = render_str
    return render_tmpl


# Traceback (UnicodeDecodeError)
dasalt:
----------
State: - file
Name:      /tmp/teststuff
Function:  recurse
Result:    False
Comment:   An exception occurred in this state: Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/salt/state.py", line 1234, in call
*cdata['args'], **cdata['kwargs'])
File "/usr/local/lib/python2.7/dist-packages/salt/states/file.py", line 1393, in recurse
manage_file(dest, src)
File "/usr/local/lib/python2.7/dist-packages/salt/states/file.py", line 1316, in manage_file
**pass_kwargs)
File "/usr/local/lib/python2.7/dist-packages/salt/states/file.py", line 886, in managed
**kwargs
File "/usr/local/lib/python2.7/dist-packages/salt/modules/file.py", line 1250, in get_managed
**kwargs)
File "/usr/local/lib/python2.7/dist-packages/salt/utils/templates.py", line 59, in render_tmpl
raise exc
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe2 in position 10: invalid continuation byte

Changes:

Summary
------------
Succeeded: 0
Failed:    1
------------
Total:     1

# Fixed code
def wrap_tmpl_func(render_str):
    def render_tmpl(
        tmplsrc, from_str=False, to_str=False, context=None, tmplpath=None, **kws
    ):
        if context is None:
            context = {}
        # We want explicit context to overwrite the **kws
        kws.update(context)
        context = kws
        assert "opts" in context
        assert "env" in context

        if isinstance(tmplsrc, basestring):
            if from_str:
                tmplstr = tmplsrc
            else:
                try:
                    with codecs.open(tmplsrc, "r", SLS_ENCODING) as _tmplsrc:
                        tmplstr = _tmplsrc.read()
                except (UnicodeDecodeError, ValueError) as exc:
                    if salt.utils.is_bin_file(tmplsrc):
                        # Template is a bin file, return the raw file
                        return dict(result=True, data=tmplsrc)
                    log.error(
                        "Exception ocurred while reading file {0}: {1}".format(
                            tmplsrc, exc
                        )
                    )
                    raise exc
        else:  # assume tmplsrc is file-like.
            tmplstr = tmplsrc.read()
            tmplsrc.close()
        try:
            output = render_str(tmplstr, context, tmplpath)
            if salt.utils.is_windows():
                # Write out with Windows newlines
                output = os.linesep.join(output.splitlines())

        except SaltTemplateRenderError as exc:
            return dict(result=False, data=str(exc))
        except Exception:
            return dict(result=False, data=traceback.format_exc())
        else:
            if to_str:  # then render as string
                return dict(result=True, data=output)
            with tempfile.NamedTemporaryFile("wb", delete=False) as outf:
                outf.write(SLS_ENCODER(output)[0])
                # Note: If nothing is replaced or added by the rendering
                #       function, then the contents of the output file will
                #       be exactly the same as the input.
            return dict(result=True, data=outf.name)

    render_tmpl.render_str = render_str
    return render_tmpl