void RequestHandlerAdaptor::onError(const HTTPException& error) noexcept {
  if (err_ != kErrorNone) {
    // we have already handled an error and upstream would have been deleted
    return;
  }

  if (error.getProxygenError() == kErrorTimeout) {
    setError(kErrorTimeout);

    if (responseStarted_) {
      sendAbort();
    } else {
      ResponseBuilder(this)
          .status(408, "Request Timeout")
          .closeConnection()
          .sendWithEOM();
    }
  } else if (error.getDirection() == HTTPException::Direction::INGRESS) {
    setError(kErrorRead);

    if (responseStarted_) {
      sendAbort();
    } else {
      ResponseBuilder(this)
          .status(400, "Bad Request")
          .closeConnection()
          .sendWithEOM();
    }

  } else {
    setError(kErrorWrite);
  }

  // Wait for detachTransaction to clean up
}
void
HTTPSessionBase::handleErrorDirectly(HTTPTransaction* txn,
                                     const HTTPException& error) {
  VLOG(4) << *this << " creating direct error handler";
  DCHECK(txn);
  auto handler = getParseErrorHandler(txn, error);
  if (!handler) {
    txn->sendAbort();
    return;
  }
  txn->setHandler(handler);
  if (infoCallback_) {
    infoCallback_->onIngressError(*this, error.getProxygenError());
  }
  txn->onError(error);
}
Exemple #3
0
void ProxygenTransport::onError(const HTTPException& err) noexcept {
  Logger::Error("HPHP transport error: %s", err.describe().c_str());
  // For now, just send a naked RST.  It's closer to the LibEventServer behavior
  m_clientTxn->sendAbort();
  requestDoneLocking();
}
void CurlClient::onError(const HTTPException& error) noexcept {
  LOG_IF(ERROR, loggingEnabled_) << "An error occurred: " << error.what();
}
void HTTPTransaction::onError(const HTTPException& error) {
  DestructorGuard g(this);

  const bool wasAborted = aborted_; // see comment below
  const bool wasEgressComplete = isEgressComplete();
  const bool wasIngressComplete = isIngressComplete();
  bool notify = (handler_);
  HTTPException::Direction direction = error.getDirection();

  if (direction == HTTPException::Direction::INGRESS &&
      isIngressEOMSeen() && isExpectingWindowUpdate()) {
    // we got an ingress error, we've seen the entire message, but we're
    // expecting more (window updates).  These aren't coming, convert to
    // INGRESS_AND_EGRESS
    VLOG(4) << *this << " Converting ingress error to ingress+egress due to"
      " flow control, and aborting";
    direction = HTTPException::Direction::INGRESS_AND_EGRESS;
    sendAbort(ErrorCode::FLOW_CONTROL_ERROR);
  }

  if (error.getProxygenError() == kErrorStreamAbort) {
    DCHECK(error.getDirection() ==
           HTTPException::Direction::INGRESS_AND_EGRESS);
    aborted_ = true;
  } else if (error.hasCodecStatusCode()) {
    DCHECK(error.getDirection() ==
           HTTPException::Direction::INGRESS_AND_EGRESS);
    sendAbort(error.getCodecStatusCode());
  }

  switch (direction) {
    case HTTPException::Direction::INGRESS_AND_EGRESS:
      markEgressComplete();
      markIngressComplete();
      if (wasEgressComplete && wasIngressComplete &&
          // We mark egress complete before we get acknowledgement of the
          // write segment finishing successfully.
          // TODO: instead of using DestructorGuard hacks to keep txn around,
          // use an explicit callback function and set egress complete after
          // last byte flushes (or egress error occurs), see #3912823
          (error.getProxygenError() != kErrorWriteTimeout || wasAborted)) {
        notify = false;
      }
      break;
    case HTTPException::Direction::EGRESS:
      markEgressComplete();
      if (!wasEgressComplete && isIngressEOMSeen() && ingressErrorSeen_) {
        // we've already seen an ingress error but we ignored it, hoping the
        // handler would resume and read our queued EOM.  Now both sides are
        // dead and we need to kill this transaction.
        markIngressComplete();
      }
      if (wasEgressComplete) {
        notify = false;
      }
      break;
    case HTTPException::Direction::INGRESS:
      if (isIngressEOMSeen()) {
        // Not an error, for now
        ingressErrorSeen_ = true;
        return;
      }
      markIngressComplete();
      if (wasIngressComplete) {
        notify = false;
      }
      break;
  }
  if (notify && handler_) {
    // mark egress complete may result in handler detaching
    handler_->onError(error);
  }
}
Exemple #6
0
void CurlClient::onError(const HTTPException& error) noexcept {
    std::cout << "on error!" << std::endl;
  LOG(ERROR) << "An error occurred: " << error.what();
}
void HTTPCodecPrinter::onError(StreamID stream,
                               const HTTPException& error,
                               bool newStream) {
    std::cout << "[Exception] " << error.what() << std::endl;
    callback_->onError(stream, error, newStream);
}