/**
  * This should be called by the member and should write a serialized root cause exception as to
  * the abort znode.
  */
 @Override
 public void sendMemberAborted(Subprocedure sub, ForeignException ee) {
   if (sub == null) {
     LOG.error("Failed due to null subprocedure", ee);
     return;
   }
   String procName = sub.getName();
   LOG.debug("Aborting procedure (" + procName + ") in zk");
   String procAbortZNode = zkController.getAbortZNode(procName);
   try {
     String source = (ee.getSource() == null) ? memberName : ee.getSource();
     byte[] errorInfo = ProtobufUtil.prependPBMagic(ForeignException.serialize(source, ee));
     ZKUtil.createAndFailSilent(zkController.getWatcher(), procAbortZNode, errorInfo);
     LOG.debug("Finished creating abort znode:" + procAbortZNode);
   } catch (KeeperException e) {
     // possible that we get this error for the procedure if we already reset the zk state, but in
     // that case we should still get an error for that procedure anyways
     zkController.logZKTree(zkController.getBaseZnode());
     member.controllerConnectionFailure(
         "Failed to post zk node:" + procAbortZNode + " to abort procedure", e, procName);
   }
 }