Clean up after failed gerrit cl description edits

If either the edit creation or edit publishing fail, we're left with
an unpublished edit hanging around. This can result in a follow-up
invocation of 'git cl desc' (e.g. if the user changes their mind, or
retries) will also fail. So, clean up after ourselves.

BUG=671091

Change-Id: Icfe53996acf2555b82be0695a3c86ebb8c50b936
Reviewed-on: https://chromium-review.googlesource.com/418449
Reviewed-by: Andrii Shyshkalov <tandrii@chromium.org>
Commit-Queue: Aaron Gable <agable@chromium.org>
diff --git a/gerrit_util.py b/gerrit_util.py
index cd2102c..07218f0 100755
--- a/gerrit_util.py
+++ b/gerrit_util.py
@@ -602,35 +602,46 @@
 
 def SetCommitMessage(host, change, description, notify='ALL'):
   """Updates a commit message."""
-  assert notify in ('ALL', 'NONE')
-  # First, edit the commit message in a draft.
-  path = 'changes/%s/edit:message' % change
-  body = {'message': description}
-  conn = CreateHttpConn(host, path, reqtype='PUT', body=body)
   try:
-    ReadHttpResponse(conn, ignore_404=False)
-  except GerritError as e:
-    # On success, gerrit returns status 204; anything else is an error.
-    if e.http_status != 204:
-      raise
-  else:
-    raise GerritError(
-        'Unexpectedly received a 200 http status while editing message in '
-        'change %s' % change)
+    assert notify in ('ALL', 'NONE')
+    # First, edit the commit message in a draft.
+    path = 'changes/%s/edit:message' % change
+    body = {'message': description}
+    conn = CreateHttpConn(host, path, reqtype='PUT', body=body)
+    try:
+      ReadHttpResponse(conn, ignore_404=False)
+    except GerritError as e:
+      # On success, gerrit returns status 204; anything else is an error.
+      if e.http_status != 204:
+        raise
+    else:
+      raise GerritError(
+          'Unexpectedly received a 200 http status while editing message in '
+          'change %s' % change)
 
-  # And then publish it.
-  path = 'changes/%s/edit:publish' % change
-  conn = CreateHttpConn(host, path, reqtype='POST', body={'notify': notify})
-  try:
-    ReadHttpResponse(conn, ignore_404=False)
-  except GerritError as e:
-    # On success, gerrit returns status 204; anything else is an error.
-    if e.http_status != 204:
-      raise
-  else:
-    raise GerritError(
-        'Unexpectedly received a 200 http status while publishing message '
-        'change in %s' % change)
+    # And then publish it.
+    path = 'changes/%s/edit:publish' % change
+    conn = CreateHttpConn(host, path, reqtype='POST', body={'notify': notify})
+    try:
+      ReadHttpResponse(conn, ignore_404=False)
+    except GerritError as e:
+      # On success, gerrit returns status 204; anything else is an error.
+      if e.http_status != 204:
+        raise
+    else:
+      raise GerritError(
+          'Unexpectedly received a 200 http status while publishing message '
+          'change in %s' % change)
+  except (GerritError, KeyboardInterrupt) as e:
+    # Something went wrong with one of the two calls, so we want to clean up
+    # after ourselves before returning.
+    try:
+      DeletePendingChangeEdit(host, change)
+    except GerritError:
+      LOGGER.error('Encountered error while cleaning up after failed attempt '
+                   'to set the CL description. You may have to delete the '
+                   'pending change edit yourself in the web UI.')
+    raise e
 
 
 def GetReviewers(host, change):