# Buggy code
def edit_config(
    obj,
    cluster_name,
    force,
    quiet,
    kvpairs,
    pgkvpairs,
    apply_filename,
    replace_filename,
):
    dcs = get_dcs(obj, cluster_name)
    cluster = dcs.get_cluster()

    before_editing = format_config_for_editing(cluster.config.data)

    after_editing = None  # Serves as a flag if any changes were requested
    changed_data = cluster.config.data

    if replace_filename:
        after_editing, changed_data = apply_yaml_file({}, replace_filename)

    if apply_filename:
        after_editing, changed_data = apply_yaml_file(changed_data, apply_filename)

    if kvpairs or pgkvpairs:
        all_pairs = list(kvpairs) + [
            "postgresql.parameters." + v.lstrip() for v in pgkvpairs
        ]
        after_editing, changed_data = apply_config_changes(
            before_editing, changed_data, all_pairs
        )

    # If no changes were specified on the command line invoke editor
    if after_editing is None:
        after_editing, changed_data = invoke_editor(before_editing, cluster_name)

    if cluster.config.data == changed_data:
        if not quiet:
            click.echo("Not changed")
        return

    if not quiet:
        show_diff(before_editing, after_editing)

    if (apply_filename == "-" or replace_filename == "-") and not force:
        click.echo("Use --force option to apply changes")
        return

    if force or click.confirm("Apply these changes?"):
        if not dcs.set_config_value(
            json.dumps(changed_data), cluster.config.modify_index
        ):
            raise PatroniCtlException(
                "Config modification aborted due to concurrent changes"
            )
        click.echo("Configuration changed")


# Traceback (kazoo.exceptions.ConnectionClosedError)
[root@postgres-5-2 ~]# patronictl -c /etc/patroni.yaml edit-config postgres-5
---
+++
@@ -11,4 +11,4 @@
use_pg_rewind: true
use_slots: true
retry_timeout: 10
-ttl: 30
+ttl: 31

Apply these changes? [y/N]: y
2017-07-28 23:27:53,965 - ERROR - Unhandled exception in connection loop
Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 541, in _connect_attempt
self._send_request(read_timeout, connect_timeout)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 445, in _send_request
self._submit(request, connect_timeout, xid)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 279, in _submit
b += request.serialize()
File "/usr/lib/python3.4/site-packages/kazoo/protocol/serialization.py", line 195, in serialize
b.extend(int_struct.pack(self.version))
struct.error: 'i' format requires -2147483648 <= number <= 2147483647
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python3.4/threading.py", line 911, in _bootstrap_inner
self.run()
File "/usr/lib64/python3.4/threading.py", line 859, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 471, in zk_loop
if retry(self._connect_loop, retry) is STOP_CONNECTING:
File "/usr/lib/python3.4/site-packages/kazoo/retry.py", line 123, in __call__
return func(*args, **kwargs)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 488, in _connect_loop
status = self._connect_attempt(host, port, retry)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 541, in _connect_attempt
self._send_request(read_timeout, connect_timeout)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 445, in _send_request
self._submit(request, connect_timeout, xid)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 279, in _submit
b += request.serialize()
File "/usr/lib/python3.4/site-packages/kazoo/protocol/serialization.py", line 195, in serialize
b.extend(int_struct.pack(self.version))
struct.error: 'i' format requires -2147483648 <= number <= 2147483647

2017-07-28 23:27:54,328 - ERROR - set_config_value
Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/patroni/dcs/zookeeper.py", line 230, in set_config_value
self._client.retry(self._client.set, self.config_path, value.encode('utf-8'), version=index or -1)
File "/usr/lib/python3.4/site-packages/kazoo/client.py", line 273, in _retry
return self._retry.copy()(*args, **kwargs)
File "/usr/lib/python3.4/site-packages/kazoo/retry.py", line 123, in __call__
return func(*args, **kwargs)
File "/usr/lib/python3.4/site-packages/kazoo/client.py", line 1219, in set
return self.set_async(path, value, version).get()
File "/usr/lib/python3.4/site-packages/kazoo/handlers/utils.py", line 72, in get
raise self._exception
kazoo.exceptions.ConnectionClosedError: Connection has been closed
Error: Config modification aborted due to concurrent changes

# Fixed code
def edit_config(
    obj,
    cluster_name,
    force,
    quiet,
    kvpairs,
    pgkvpairs,
    apply_filename,
    replace_filename,
):
    dcs = get_dcs(obj, cluster_name)
    cluster = dcs.get_cluster()

    before_editing = format_config_for_editing(cluster.config.data)

    after_editing = None  # Serves as a flag if any changes were requested
    changed_data = cluster.config.data

    if replace_filename:
        after_editing, changed_data = apply_yaml_file({}, replace_filename)

    if apply_filename:
        after_editing, changed_data = apply_yaml_file(changed_data, apply_filename)

    if kvpairs or pgkvpairs:
        all_pairs = list(kvpairs) + [
            "postgresql.parameters." + v.lstrip() for v in pgkvpairs
        ]
        after_editing, changed_data = apply_config_changes(
            before_editing, changed_data, all_pairs
        )

    # If no changes were specified on the command line invoke editor
    if after_editing is None:
        after_editing, changed_data = invoke_editor(before_editing, cluster_name)

    if cluster.config.data == changed_data:
        if not quiet:
            click.echo("Not changed")
        return

    if not quiet:
        show_diff(before_editing, after_editing)

    if (apply_filename == "-" or replace_filename == "-") and not force:
        click.echo("Use --force option to apply changes")
        return

    if force or click.confirm("Apply these changes?"):
        if not dcs.set_config_value(json.dumps(changed_data), cluster.config.index):
            raise PatroniCtlException(
                "Config modification aborted due to concurrent changes"
            )
        click.echo("Configuration changed")