void HTTPSession::onAbort(HTTPCodec::StreamID streamID,
                          ErrorCode code) {
  VLOG(4) << "stream abort on " << *this << ", streamID=" << streamID
          << ", code=" << getErrorCodeString(code);
  HTTPTransaction* txn = findTransaction(streamID);
  if (!txn) {
    VLOG(4) << *this << " abort for unrecognized transaction, streamID= "
      << streamID;
    return;
  }
  HTTPException ex(HTTPException::Direction::INGRESS_AND_EGRESS,
    folly::to<std::string>("Stream aborted, streamID=",
      streamID, ", code=", getErrorCodeString(code)));
  ex.setProxygenError(kErrorStreamAbort);
  ex.setCodecStatusCode(code);
  DestructorGuard dg(this);
  if (isDownstream() && !txn->getAssocTxnId() && code == ErrorCode::CANCEL) {
    // Cancelling the assoc txn cancels all push txns
    for (auto it = txn->getPushedTransactions().begin();
         it != txn->getPushedTransactions().end(); ) {
      auto pushTxn = findTransaction(*it);
      ++it;
      DCHECK(pushTxn != nullptr);
      pushTxn->onError(ex);
    }
  }
  auto exTxns = txn->getExTransactions();
  for (auto it = exTxns.begin(); it != exTxns.end(); ++it) {
    auto exTxn = findTransaction(*it);
    if (exTxn) {
      exTxn->onError(ex);
    }
  }
  txn->onError(ex);
}
void HTTPSession::onAbort(HTTPCodec::StreamID streamID,
                          ErrorCode code) {
  VLOG(4) << "stream abort on " << *this << ", streamID=" << streamID
          << ", code=" << getErrorCodeString(code);
  HTTPTransaction* txn = findTransaction(streamID);
  if (!txn) {
    VLOG(4) << *this << " abort for unrecognized transaction, streamID= "
      << streamID;
    return;
  }
  HTTPException ex(HTTPException::Direction::INGRESS_AND_EGRESS,
    folly::to<std::string>("Stream aborted, streamID=",
      streamID, ", code=", getErrorCodeString(code)));
  ex.setProxygenError(kErrorStreamAbort);
  ex.setCodecStatusCode(code);
  DestructorGuard dg(this);
  if (isDownstream() && !txn->getAssocTxnId() && code == ErrorCode::CANCEL) {
     
    for (auto it = txn->getPushedTransactions().begin();
         it != txn->getPushedTransactions().end(); ) {
      auto pushTxn = findTransaction(*it);
      ++it;
      DCHECK(pushTxn != nullptr);
      pushTxn->onError(ex);
    }
  }
  auto exTxns = txn->getExTransactions();
  for (auto it = exTxns.begin(); it != exTxns.end(); ++it) {
    auto exTxn = findTransaction(*it);
    if (exTxn) {
      exTxn->onError(ex);
    }
  }
  txn->onError(ex);
}