# Buggy code
def set_mode_if_different(self, path, mode, changed, diff=None, expand=True):
    b_path = to_bytes(path, errors="surrogate_then_strict")
    if expand:
        b_path = os.path.expanduser(os.path.expandvars(b_path))
    path = to_text(b_path, errors="surrogate_then_strict")
    path_stat = os.lstat(b_path)

    if mode is None:
        return changed

    if not isinstance(mode, int):
        try:
            mode = int(mode, 8)
        except Exception:
            try:
                mode = self._symbolic_mode_to_octal(path_stat, mode)
            except Exception:
                e = get_exception()
                self.fail_json(
                    path=path,
                    msg="mode must be in octal or symbolic form",
                    details=str(e),
                )

            if mode != stat.S_IMODE(mode):
                # prevent mode from having extra info orbeing invalid long number
                self.fail_json(
                    path=path,
                    msg="Invalid mode supplied, only permission info is allowed",
                    details=mode,
                )

    prev_mode = stat.S_IMODE(path_stat.st_mode)

    if prev_mode != mode:
        if diff is not None:
            if "before" not in diff:
                diff["before"] = {}
            diff["before"]["mode"] = "0%03o" % prev_mode
            if "after" not in diff:
                diff["after"] = {}
            diff["after"]["mode"] = "0%03o" % mode

        if self.check_mode:
            return True
        # FIXME: comparison against string above will cause this to be executed
        # every time
        try:
            if hasattr(os, "lchmod"):
                os.lchmod(b_path, mode)
            else:
                if not os.path.islink(b_path):
                    os.chmod(b_path, mode)
                else:
                    # Attempt to set the perms of the symlink but be
                    # careful not to change the perms of the underlying
                    # file while trying
                    underlying_stat = os.stat(b_path)
                    os.chmod(b_path, mode)
                    new_underlying_stat = os.stat(b_path)
                    if underlying_stat.st_mode != new_underlying_stat.st_mode:
                        os.chmod(b_path, stat.S_IMODE(underlying_stat.st_mode))
        except OSError:
            e = get_exception()
            if (
                os.path.islink(b_path) and e.errno == errno.EPERM
            ):  # Can't set mode on symbolic links
                pass
            elif e.errno in (
                errno.ENOENT,
                errno.ELOOP,
            ):  # Can't set mode on broken symbolic links
                pass
            else:
                raise e
        except Exception:
            e = get_exception()
            self.fail_json(path=path, msg="chmod failed", details=str(e))

        path_stat = os.lstat(b_path)
        new_mode = stat.S_IMODE(path_stat.st_mode)

        if new_mode != prev_mode:
            changed = True
    return changed


# Traceback (LookupError)
exception:
Traceback (most recent call last):
File "/tmp/ansible_atAUEE/ansible_module_file.py", line 480, in <module>
main()
File "/tmp/ansible_atAUEE/ansible_module_file.py", line 362, in main
changed |= recursive_set_attributes(module, to_bytes(file_args['path'], errors='surrogate_or_strict'), follow, file_args)
File "/tmp/ansible_atAUEE/ansible_module_file.py", line 171, in recursive_set_attributes
changed |= module.set_fs_attributes_if_different(tmp_file_args, changed)
File "/tmp/ansible_atAUEE/ansible_modlib.zip/ansible/module_utils/basic.py", line 1292, in set_fs_attributes_if_different
File "/tmp/ansible_atAUEE/ansible_modlib.zip/ansible/module_utils/basic.py", line 995, in set_owner_if_different
File "/tmp/ansible_atAUEE/ansible_modlib.zip/ansible/module_utils/_text.py", line 232, in to_text
File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
LookupError: unknown error handler name 'surrogate_then_strict'

# Fixed code
def set_mode_if_different(self, path, mode, changed, diff=None, expand=True):
    b_path = to_bytes(path, errors="surrogate_or_strict")
    if expand:
        b_path = os.path.expanduser(os.path.expandvars(b_path))
    path = to_text(b_path, errors="surrogate_or_strict")
    path_stat = os.lstat(b_path)

    if mode is None:
        return changed

    if not isinstance(mode, int):
        try:
            mode = int(mode, 8)
        except Exception:
            try:
                mode = self._symbolic_mode_to_octal(path_stat, mode)
            except Exception:
                e = get_exception()
                self.fail_json(
                    path=path,
                    msg="mode must be in octal or symbolic form",
                    details=str(e),
                )

            if mode != stat.S_IMODE(mode):
                # prevent mode from having extra info orbeing invalid long number
                self.fail_json(
                    path=path,
                    msg="Invalid mode supplied, only permission info is allowed",
                    details=mode,
                )

    prev_mode = stat.S_IMODE(path_stat.st_mode)

    if prev_mode != mode:
        if diff is not None:
            if "before" not in diff:
                diff["before"] = {}
            diff["before"]["mode"] = "0%03o" % prev_mode
            if "after" not in diff:
                diff["after"] = {}
            diff["after"]["mode"] = "0%03o" % mode

        if self.check_mode:
            return True
        # FIXME: comparison against string above will cause this to be executed
        # every time
        try:
            if hasattr(os, "lchmod"):
                os.lchmod(b_path, mode)
            else:
                if not os.path.islink(b_path):
                    os.chmod(b_path, mode)
                else:
                    # Attempt to set the perms of the symlink but be
                    # careful not to change the perms of the underlying
                    # file while trying
                    underlying_stat = os.stat(b_path)
                    os.chmod(b_path, mode)
                    new_underlying_stat = os.stat(b_path)
                    if underlying_stat.st_mode != new_underlying_stat.st_mode:
                        os.chmod(b_path, stat.S_IMODE(underlying_stat.st_mode))
        except OSError:
            e = get_exception()
            if (
                os.path.islink(b_path) and e.errno == errno.EPERM
            ):  # Can't set mode on symbolic links
                pass
            elif e.errno in (
                errno.ENOENT,
                errno.ELOOP,
            ):  # Can't set mode on broken symbolic links
                pass
            else:
                raise e
        except Exception:
            e = get_exception()
            self.fail_json(path=path, msg="chmod failed", details=str(e))

        path_stat = os.lstat(b_path)
        new_mode = stat.S_IMODE(path_stat.st_mode)

        if new_mode != prev_mode:
            changed = True
    return changed