Change QuicStream::CloseConnectionWithDetails() to QuicStream::OnUnrecoverableError.

The stream shouldn't be able to instruct the session on what to do. Instead, it should just report its state change and let the session handle it.

gfe-relnote: name change only. Not protected.
PiperOrigin-RevId: 294966339
Change-Id: Ibff2ed7169d0964ea5f19823445f5aa9ce8c5916
diff --git a/quic/core/http/quic_headers_stream.cc b/quic/core/http/quic_headers_stream.cc
index 5b1a87b..1bac2b7 100644
--- a/quic/core/http/quic_headers_stream.cc
+++ b/quic/core/http/quic_headers_stream.cc
@@ -85,8 +85,8 @@
       if (header.unacked_length < header_length) {
         QUIC_BUG << "Unsent stream data is acked. unacked_length: "
                  << header.unacked_length << " acked_length: " << header_length;
-        CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
-                                   "Unsent stream data is acked");
+        OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                             "Unsent stream data is acked");
         return false;
       }
       if (header.ack_listener != nullptr && header_length > 0) {
diff --git a/quic/core/http/quic_receive_control_stream.cc b/quic/core/http/quic_receive_control_stream.cc
index ab7a55b..6e7389b 100644
--- a/quic/core/http/quic_receive_control_stream.cc
+++ b/quic/core/http/quic_receive_control_stream.cc
@@ -26,13 +26,11 @@
   HttpDecoderVisitor& operator=(const HttpDecoderVisitor&) = delete;
 
   void OnError(HttpDecoder* decoder) override {
-    stream_->session()->connection()->CloseConnection(
-        decoder->error(), decoder->error_detail(),
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    stream_->OnUnrecoverableError(decoder->error(), decoder->error_detail());
   }
 
   bool OnCancelPushFrame(const CancelPushFrame& /*frame*/) override {
-    CloseConnectionOnWrongFrame("Cancel Push");
+    OnWrongFrame("Cancel Push");
     return false;
   }
 
@@ -41,13 +39,13 @@
       stream_->spdy_session()->SetMaxAllowedPushId(frame.push_id);
       return true;
     }
-    CloseConnectionOnWrongFrame("Max Push Id");
+    OnWrongFrame("Max Push Id");
     return false;
   }
 
   bool OnGoAwayFrame(const GoAwayFrame& frame) override {
     if (stream_->spdy_session()->perspective() == Perspective::IS_SERVER) {
-      CloseConnectionOnWrongFrame("Go Away");
+      OnWrongFrame("Go Away");
       return false;
     }
     stream_->spdy_session()->OnHttp3GoAway(frame.stream_id);
@@ -63,59 +61,59 @@
   }
 
   bool OnDuplicatePushFrame(const DuplicatePushFrame& /*frame*/) override {
-    CloseConnectionOnWrongFrame("Duplicate Push");
+    OnWrongFrame("Duplicate Push");
     return false;
   }
 
   bool OnDataFrameStart(QuicByteCount /*header_length*/) override {
-    CloseConnectionOnWrongFrame("Data");
+    OnWrongFrame("Data");
     return false;
   }
 
   bool OnDataFramePayload(quiche::QuicheStringPiece /*payload*/) override {
-    CloseConnectionOnWrongFrame("Data");
+    OnWrongFrame("Data");
     return false;
   }
 
   bool OnDataFrameEnd() override {
-    CloseConnectionOnWrongFrame("Data");
+    OnWrongFrame("Data");
     return false;
   }
 
   bool OnHeadersFrameStart(QuicByteCount /*header_length*/) override {
-    CloseConnectionOnWrongFrame("Headers");
+    OnWrongFrame("Headers");
     return false;
   }
 
   bool OnHeadersFramePayload(quiche::QuicheStringPiece /*payload*/) override {
-    CloseConnectionOnWrongFrame("Headers");
+    OnWrongFrame("Headers");
     return false;
   }
 
   bool OnHeadersFrameEnd() override {
-    CloseConnectionOnWrongFrame("Headers");
+    OnWrongFrame("Headers");
     return false;
   }
 
   bool OnPushPromiseFrameStart(QuicByteCount /*header_length*/) override {
-    CloseConnectionOnWrongFrame("Push Promise");
+    OnWrongFrame("Push Promise");
     return false;
   }
 
   bool OnPushPromiseFramePushId(PushId /*push_id*/,
                                 QuicByteCount /*push_id_length*/) override {
-    CloseConnectionOnWrongFrame("Push Promise");
+    OnWrongFrame("Push Promise");
     return false;
   }
 
   bool OnPushPromiseFramePayload(
       quiche::QuicheStringPiece /*payload*/) override {
-    CloseConnectionOnWrongFrame("Push Promise");
+    OnWrongFrame("Push Promise");
     return false;
   }
 
   bool OnPushPromiseFrameEnd() override {
-    CloseConnectionOnWrongFrame("Push Promise");
+    OnWrongFrame("Push Promise");
     return false;
   }
 
@@ -144,8 +142,8 @@
   }
 
  private:
-  void CloseConnectionOnWrongFrame(quiche::QuicheStringPiece frame_type) {
-    stream_->CloseConnectionWithDetails(
+  void OnWrongFrame(quiche::QuicheStringPiece frame_type) {
+    stream_->OnUnrecoverableError(
         QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
         quiche::QuicheStrCat(frame_type, " frame received on control stream"));
   }
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc
index 67234a9..8625dae 100644
--- a/quic/core/http/quic_spdy_stream.cc
+++ b/quic/core/http/quic_spdy_stream.cc
@@ -41,8 +41,7 @@
   HttpDecoderVisitor& operator=(const HttpDecoderVisitor&) = delete;
 
   void OnError(HttpDecoder* decoder) override {
-    stream_->CloseConnectionWithDetails(decoder->error(),
-                                        decoder->error_detail());
+    stream_->OnUnrecoverableError(decoder->error(), decoder->error_detail());
   }
 
   bool OnCancelPushFrame(const CancelPushFrame& /*frame*/) override {
@@ -169,7 +168,7 @@
 
  private:
   void CloseConnectionOnWrongFrame(quiche::QuicheStringPiece frame_type) {
-    stream_->CloseConnectionWithDetails(
+    stream_->OnUnrecoverableError(
         QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM,
         quiche::QuicheStrCat(frame_type, " frame received on data stream"));
   }
@@ -577,8 +576,8 @@
   std::string connection_close_error_message = quiche::QuicheStrCat(
       "Error decoding ", headers_decompressed_ ? "trailers" : "headers",
       " on stream ", id(), ": ", error_message);
-  CloseConnectionWithDetails(QUIC_QPACK_DECOMPRESSION_FAILED,
-                             connection_close_error_message);
+  OnUnrecoverableError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                       connection_close_error_message);
 }
 
 void QuicSpdyStream::MaybeSendPriorityUpdateFrame() {
@@ -607,8 +606,8 @@
     // or with H3_REQUEST_REJECTED (if server).
     std::string error_message =
         quiche::QuicheStrCat("Too large headers received on stream ", id());
-    CloseConnectionWithDetails(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
-                               error_message);
+    OnUnrecoverableError(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
+                         error_message);
   } else {
     Reset(QUIC_HEADERS_TOO_LARGE);
   }
diff --git a/quic/core/quic_crypto_client_handshaker.cc b/quic/core/quic_crypto_client_handshaker.cc
index 3614433..d9e67db 100644
--- a/quic/core/quic_crypto_client_handshaker.cc
+++ b/quic/core/quic_crypto_client_handshaker.cc
@@ -83,7 +83,7 @@
   QuicCryptoHandshaker::OnHandshakeMessage(message);
   if (message.tag() == kSCUP) {
     if (!one_rtt_keys_available()) {
-      stream_->CloseConnectionWithDetails(
+      stream_->OnUnrecoverableError(
           QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
           "Early SCUP disallowed");
       return;
@@ -98,9 +98,8 @@
 
   // Do not process handshake messages after the handshake is confirmed.
   if (one_rtt_keys_available()) {
-    stream_->CloseConnectionWithDetails(
-        QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
-        "Unexpected handshake message");
+    stream_->OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+                                  "Unexpected handshake message");
     return;
   }
 
@@ -184,7 +183,7 @@
       crypto_negotiated_params_, &error_details);
 
   if (error != QUIC_NO_ERROR) {
-    stream_->CloseConnectionWithDetails(
+    stream_->OnUnrecoverableError(
         error, "Server config update invalid: " + error_details);
     return;
   }
@@ -229,8 +228,8 @@
         break;
       case STATE_IDLE:
         // This means that the peer sent us a message that we weren't expecting.
-        stream_->CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                                            "Handshake in idle state");
+        stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                      "Handshake in idle state");
         return;
       case STATE_INITIALIZE_SCUP:
         DoInitializeServerConfigUpdate(cached);
@@ -266,7 +265,7 @@
   session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
   encryption_established_ = false;
   if (num_client_hellos_ >= QuicCryptoClientStream::kMaxClientHellos) {
-    stream_->CloseConnectionWithDetails(
+    stream_->OnUnrecoverableError(
         QUIC_CRYPTO_TOO_MANY_REJECTS,
         quiche::QuicheStrCat("More than ",
                              QuicCryptoClientStream::kMaxClientHellos,
@@ -294,14 +293,13 @@
     if (max_packet_size <= kFramingOverhead) {
       QUIC_DLOG(DFATAL) << "max_packet_length (" << max_packet_size
                         << ") has no room for framing overhead.";
-      stream_->CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
-                                          "max_packet_size too smalll");
+      stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                                    "max_packet_size too smalll");
       return;
     }
     if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
       QUIC_DLOG(DFATAL) << "Client hello won't fit in a single packet.";
-      stream_->CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
-                                          "CHLO too large");
+      stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR, "CHLO too large");
       return;
     }
     next_state_ = STATE_RECV_REJ;
@@ -324,7 +322,7 @@
     // Flush the cached config so that, if it's bad, the server has a
     // chance to send us another in the future.
     cached->InvalidateServerConfig();
-    stream_->CloseConnectionWithDetails(error, error_details);
+    stream_->OnUnrecoverableError(error, error_details);
     return;
   }
   chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
@@ -358,8 +356,8 @@
   // that we need.
   if (in->tag() != kREJ) {
     next_state_ = STATE_NONE;
-    stream_->CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                                        "Expected REJ");
+    stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                  "Expected REJ");
     return;
   }
 
@@ -397,7 +395,7 @@
 
   if (error != QUIC_NO_ERROR) {
     next_state_ = STATE_NONE;
-    stream_->CloseConnectionWithDetails(error, error_details);
+    stream_->OnUnrecoverableError(error, error_details);
     return;
   }
   if (!cached->proof_valid()) {
@@ -468,8 +466,8 @@
     next_state_ = STATE_NONE;
     QUIC_CLIENT_HISTOGRAM_BOOL("QuicVerifyProofFailed.HandshakeConfirmed",
                                one_rtt_keys_available(), "");
-    stream_->CloseConnectionWithDetails(
-        QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
+    stream_->OnUnrecoverableError(QUIC_PROOF_INVALID,
+                                  "Proof invalid: " + verify_error_details_);
     return;
   }
 
@@ -501,8 +499,8 @@
     // A reject message must be sent in ENCRYPTION_INITIAL.
     if (session()->connection()->last_decrypted_level() != ENCRYPTION_INITIAL) {
       // The rejection was sent encrypted!
-      stream_->CloseConnectionWithDetails(
-          QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, "encrypted REJ message");
+      stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
+                                    "encrypted REJ message");
       return;
     }
     next_state_ = STATE_RECV_REJ;
@@ -510,7 +508,7 @@
   }
 
   if (in->tag() != kSHLO) {
-    stream_->CloseConnectionWithDetails(
+    stream_->OnUnrecoverableError(
         QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
         quiche::QuicheStrCat("Expected SHLO or REJ. Received: ",
                              QuicTagToString(in->tag())));
@@ -519,8 +517,8 @@
 
   if (session()->connection()->last_decrypted_level() == ENCRYPTION_INITIAL) {
     // The server hello was sent without encryption.
-    stream_->CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
-                                        "unencrypted SHLO message");
+    stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
+                                  "unencrypted SHLO message");
     return;
   }
 
@@ -532,14 +530,14 @@
       crypto_negotiated_params_, &error_details);
 
   if (error != QUIC_NO_ERROR) {
-    stream_->CloseConnectionWithDetails(
-        error, "Server hello invalid: " + error_details);
+    stream_->OnUnrecoverableError(error,
+                                  "Server hello invalid: " + error_details);
     return;
   }
   error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
   if (error != QUIC_NO_ERROR) {
-    stream_->CloseConnectionWithDetails(
-        error, "Server hello invalid: " + error_details);
+    stream_->OnUnrecoverableError(error,
+                                  "Server hello invalid: " + error_details);
     return;
   }
   session()->OnConfigNegotiated();
diff --git a/quic/core/quic_crypto_server_handshaker.cc b/quic/core/quic_crypto_server_handshaker.cc
index 2f1f061..6150642 100644
--- a/quic/core/quic_crypto_server_handshaker.cc
+++ b/quic/core/quic_crypto_server_handshaker.cc
@@ -101,15 +101,14 @@
 
   // Do not process handshake messages after the handshake is confirmed.
   if (one_rtt_keys_available_) {
-    stream_->CloseConnectionWithDetails(
-        QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
-        "Unexpected handshake message from client");
+    stream_->OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+                                  "Unexpected handshake message from client");
     return;
   }
 
   if (message.tag() != kCHLO) {
-    stream_->CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                                        "Handshake packet not CHLO");
+    stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                  "Handshake packet not CHLO");
     return;
   }
 
@@ -118,7 +117,7 @@
     // Already processing some other handshake message.  The protocol
     // does not allow for clients to send multiple handshake messages
     // before the server has a chance to respond.
-    stream_->CloseConnectionWithDetails(
+    stream_->OnUnrecoverableError(
         QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
         "Unexpected handshake message while processing CHLO");
     return;
@@ -167,7 +166,7 @@
 
   const CryptoHandshakeMessage& message = result.client_hello;
   if (error != QUIC_NO_ERROR) {
-    stream_->CloseConnectionWithDetails(error, error_details);
+    stream_->OnUnrecoverableError(error, error_details);
     return;
   }
 
@@ -187,7 +186,7 @@
   const QuicErrorCode process_error =
       config->ProcessPeerHello(message, CLIENT, &process_error_details);
   if (process_error != QUIC_NO_ERROR) {
-    stream_->CloseConnectionWithDetails(process_error, process_error_details);
+    stream_->OnUnrecoverableError(process_error, process_error_details);
     return;
   }
 
diff --git a/quic/core/quic_crypto_stream.cc b/quic/core/quic_crypto_stream.cc
index 6f92f3f..8e32448 100644
--- a/quic/core/quic_crypto_stream.cc
+++ b/quic/core/quic_crypto_stream.cc
@@ -75,8 +75,8 @@
   EncryptionLevel frame_level = level;
   if (substreams_[level].sequencer.NumBytesBuffered() >
       BufferSizeLimitForLevel(frame_level)) {
-    CloseConnectionWithDetails(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-                               "Too much crypto data received");
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Too much crypto data received");
   }
 }
 
@@ -84,8 +84,7 @@
   if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
     QUIC_PEER_BUG
         << "Crypto data received in stream frame instead of crypto frame";
-    CloseConnectionWithDetails(QUIC_INVALID_STREAM_DATA,
-                               "Unexpected stream frame");
+    OnUnrecoverableError(QUIC_INVALID_STREAM_DATA, "Unexpected stream frame");
   }
   QuicStream::OnStreamFrame(frame);
 }
@@ -110,8 +109,8 @@
     quiche::QuicheStringPiece data(static_cast<char*>(iov.iov_base),
                                    iov.iov_len);
     if (!crypto_message_parser()->ProcessInput(data, level)) {
-      CloseConnectionWithDetails(crypto_message_parser()->error(),
-                                 crypto_message_parser()->error_detail());
+      OnUnrecoverableError(crypto_message_parser()->error(),
+                           crypto_message_parser()->error_detail());
       return;
     }
     sequencer->MarkConsumed(iov.iov_len);
@@ -163,8 +162,8 @@
     QUIC_BUG << "Writing too much crypto handshake data";
     // TODO(nharper): Switch this to an IETF QUIC error code, possibly
     // INTERNAL_ERROR?
-    CloseConnectionWithDetails(QUIC_STREAM_LENGTH_OVERFLOW,
-                               "Writing too much crypto handshake data");
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Writing too much crypto handshake data");
   }
   if (had_buffered_data) {
     // Do not try to write if there is buffered data.
@@ -191,8 +190,8 @@
   QuicByteCount newly_acked_length = 0;
   if (!substreams_[frame.level].send_buffer.OnStreamDataAcked(
           frame.offset, frame.data_length, &newly_acked_length)) {
-    CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
-                               "Trying to ack unsent crypto data.");
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Trying to ack unsent crypto data.");
     return false;
   }
   return newly_acked_length > 0;
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc
index 9d8407a..5331c37 100644
--- a/quic/core/quic_stream.cc
+++ b/quic/core/quic_stream.cc
@@ -150,8 +150,8 @@
   QUIC_NOTREACHED();
 }
 
-void PendingStream::CloseConnectionWithDetails(QuicErrorCode error,
-                                               const std::string& details) {
+void PendingStream::OnUnrecoverableError(QuicErrorCode error,
+                                         const std::string& details) {
   stream_delegate_->OnStreamError(error, details);
 }
 
@@ -174,14 +174,13 @@
     QUIC_PEER_BUG
         << "Receive stream frame reaches max stream length. frame offset "
         << frame.offset << " length " << frame.data_length;
-    CloseConnectionWithDetails(
-        QUIC_STREAM_LENGTH_OVERFLOW,
-        "Peer sends more data than allowed on this stream.");
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Peer sends more data than allowed on this stream.");
     return;
   }
 
   if (frame.offset + frame.data_length > sequencer_.close_offset()) {
-    CloseConnectionWithDetails(
+    OnUnrecoverableError(
         QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
         quiche::QuicheStrCat(
             "Stream ", id_,
@@ -206,9 +205,8 @@
     // violation of flow control.
     if (flow_controller_.FlowControlViolation() ||
         connection_flow_controller_->FlowControlViolation()) {
-      CloseConnectionWithDetails(
-          QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-          "Flow control violation after increasing offset");
+      OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                           "Flow control violation after increasing offset");
       return;
     }
   }
@@ -221,8 +219,8 @@
 
   if (frame.byte_offset > kMaxStreamLength) {
     // Peer are not suppose to write bytes more than maxium allowed.
-    CloseConnectionWithDetails(QUIC_STREAM_LENGTH_OVERFLOW,
-                               "Reset frame stream offset overflow.");
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Reset frame stream offset overflow.");
     return;
   }
 
@@ -230,7 +228,7 @@
       std::numeric_limits<QuicStreamOffset>::max();
   if (sequencer()->close_offset() != kMaxOffset &&
       frame.byte_offset != sequencer()->close_offset()) {
-    CloseConnectionWithDetails(
+    OnUnrecoverableError(
         QUIC_STREAM_MULTIPLE_OFFSET,
         quiche::QuicheStrCat("Stream ", id_,
                              " received new final offset: ", frame.byte_offset,
@@ -242,9 +240,8 @@
   MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
   if (flow_controller_.FlowControlViolation() ||
       connection_flow_controller_->FlowControlViolation()) {
-    CloseConnectionWithDetails(
-        QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-        "Flow control violation after increasing offset");
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Flow control violation after increasing offset");
     return;
   }
 }
@@ -398,9 +395,8 @@
   DCHECK(!(read_side_closed_ && write_side_closed_));
 
   if (type_ == WRITE_UNIDIRECTIONAL) {
-    CloseConnectionWithDetails(
-        QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM,
-        "Data received on write unidirectional stream");
+    OnUnrecoverableError(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM,
+                         "Data received on write unidirectional stream");
     return;
   }
 
@@ -413,7 +409,7 @@
                   << " reaches max stream length. frame offset " << frame.offset
                   << " length " << frame.data_length << ". "
                   << sequencer_.DebugString();
-    CloseConnectionWithDetails(
+    OnUnrecoverableError(
         QUIC_STREAM_LENGTH_OVERFLOW,
         quiche::QuicheStrCat("Peer sends more data than allowed on stream ",
                              id_, ". frame: offset = ", frame.offset,
@@ -423,7 +419,7 @@
   }
 
   if (frame.offset + frame.data_length > sequencer_.close_offset()) {
-    CloseConnectionWithDetails(
+    OnUnrecoverableError(
         QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
         quiche::QuicheStrCat(
             "Stream ", id_,
@@ -459,9 +455,8 @@
     // violation of flow control.
     if (flow_controller_->FlowControlViolation() ||
         connection_flow_controller_->FlowControlViolation()) {
-      CloseConnectionWithDetails(
-          QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-          "Flow control violation after increasing offset");
+      OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                           "Flow control violation after increasing offset");
       return;
     }
   }
@@ -481,8 +476,8 @@
   rst_received_ = true;
   if (frame.byte_offset > kMaxStreamLength) {
     // Peer are not suppose to write bytes more than maxium allowed.
-    CloseConnectionWithDetails(QUIC_STREAM_LENGTH_OVERFLOW,
-                               "Reset frame stream offset overflow.");
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Reset frame stream offset overflow.");
     return;
   }
 
@@ -490,7 +485,7 @@
       std::numeric_limits<QuicStreamOffset>::max();
   if (sequencer()->close_offset() != kMaxOffset &&
       frame.byte_offset != sequencer()->close_offset()) {
-    CloseConnectionWithDetails(
+    OnUnrecoverableError(
         QUIC_STREAM_MULTIPLE_OFFSET,
         quiche::QuicheStrCat("Stream ", id_,
                              " received new final offset: ", frame.byte_offset,
@@ -502,9 +497,8 @@
   MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
   if (flow_controller_->FlowControlViolation() ||
       connection_flow_controller_->FlowControlViolation()) {
-    CloseConnectionWithDetails(
-        QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-        "Flow control violation after increasing offset");
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Flow control violation after increasing offset");
     return;
   }
 
@@ -549,8 +543,8 @@
   rst_sent_ = true;
 }
 
-void QuicStream::CloseConnectionWithDetails(QuicErrorCode error,
-                                            const std::string& details) {
+void QuicStream::OnUnrecoverableError(QuicErrorCode error,
+                                      const std::string& details) {
   stream_delegate_->OnStreamError(error, details);
 }
 
@@ -583,9 +577,8 @@
     QUIC_DLOG(ERROR) << ENDPOINT
                      << "Attempt to write when the write side is closed";
     if (type_ == READ_UNIDIRECTIONAL) {
-      CloseConnectionWithDetails(
-          QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
-          "Try to send data on read unidirectional stream");
+      OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
+                           "Try to send data on read unidirectional stream");
     }
     return;
   }
@@ -600,7 +593,7 @@
     QuicStreamOffset offset = send_buffer_.stream_offset();
     if (kMaxStreamLength - offset < data.length()) {
       QUIC_BUG << "Write too many data via stream " << id_;
-      CloseConnectionWithDetails(
+      OnUnrecoverableError(
           QUIC_STREAM_LENGTH_OVERFLOW,
           quiche::QuicheStrCat("Write too many data via stream ", id_));
       return;
@@ -678,9 +671,8 @@
     QUIC_DLOG(ERROR) << ENDPOINT << "Stream " << id()
                      << " attempting to write when the write side is closed";
     if (type_ == READ_UNIDIRECTIONAL) {
-      CloseConnectionWithDetails(
-          QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
-          "Try to send data on read unidirectional stream");
+      OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
+                           "Try to send data on read unidirectional stream");
     }
     return consumed_data;
   }
@@ -695,7 +687,7 @@
       if (offset > send_buffer_.stream_offset() ||
           kMaxStreamLength < send_buffer_.stream_offset()) {
         QUIC_BUG << "Write too many data via stream " << id_;
-        CloseConnectionWithDetails(
+        OnUnrecoverableError(
             QUIC_STREAM_LENGTH_OVERFLOW,
             quiche::QuicheStrCat("Write too many data via stream ", id_));
         return consumed_data;
@@ -805,7 +797,7 @@
 
 void QuicStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
   if (type_ == READ_UNIDIRECTIONAL) {
-    CloseConnectionWithDetails(
+    OnUnrecoverableError(
         QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
         "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.");
     return;
@@ -882,13 +874,11 @@
   *newly_acked_length = 0;
   if (!send_buffer_.OnStreamDataAcked(offset, data_length,
                                       newly_acked_length)) {
-    CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
-                               "Trying to ack unsent data.");
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent data.");
     return false;
   }
   if (!fin_sent_ && fin_acked) {
-    CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
-                               "Trying to ack unsent fin.");
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent fin.");
     return false;
   }
   // Indicates whether ack listener's OnPacketAcked should be called.
diff --git a/quic/core/quic_stream.h b/quic/core/quic_stream.h
index 1d05292..c182031 100644
--- a/quic/core/quic_stream.h
+++ b/quic/core/quic_stream.h
@@ -59,8 +59,8 @@
   void OnFinRead() override;
   void AddBytesConsumed(QuicByteCount bytes) override;
   void Reset(QuicRstStreamErrorCode error) override;
-  void CloseConnectionWithDetails(QuicErrorCode error,
-                                  const std::string& details) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& details) override;
   QuicStreamId id() const override;
   const QuicSocketAddress& PeerAddressOfLatestPacket() const override;
 
@@ -155,8 +155,8 @@
 
   // Called by the subclass or the sequencer to close the entire connection from
   // this end.
-  void CloseConnectionWithDetails(QuicErrorCode error,
-                                  const std::string& details) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& details) override;
 
   // Get peer IP of the lastest packet which connection is dealing/delt with.
   const QuicSocketAddress& PeerAddressOfLatestPacket() const override;
diff --git a/quic/core/quic_stream_sequencer.cc b/quic/core/quic_stream_sequencer.cc
index 79c2df7..c4c7f66 100644
--- a/quic/core/quic_stream_sequencer.cc
+++ b/quic/core/quic_stream_sequencer.cc
@@ -74,7 +74,7 @@
         "\nPeer Address: ", stream_->PeerAddressOfLatestPacket().ToString());
     QUIC_LOG_FIRST_N(WARNING, 50) << QuicErrorCodeToString(result);
     QUIC_LOG_FIRST_N(WARNING, 50) << details;
-    stream_->CloseConnectionWithDetails(result, details);
+    stream_->OnUnrecoverableError(result, details);
     return;
   }
 
@@ -117,7 +117,7 @@
 
   // If there is a scheduled close, the new offset should match it.
   if (close_offset_ != kMaxOffset && offset != close_offset_) {
-    stream_->CloseConnectionWithDetails(
+    stream_->OnUnrecoverableError(
         QUIC_STREAM_SEQUENCER_INVALID_STATE,
         quiche::QuicheStrCat(
             "Stream ", stream_->id(), " received new final offset: ", offset,
@@ -128,7 +128,7 @@
   // The final offset should be no less than the highest offset that is
   // received.
   if (offset < highest_offset_) {
-    stream_->CloseConnectionWithDetails(
+    stream_->OnUnrecoverableError(
         QUIC_STREAM_SEQUENCER_INVALID_STATE,
         quiche::QuicheStrCat(
             "Stream ", stream_->id(), " received fin with offset: ", offset,
@@ -197,7 +197,7 @@
   if (read_error != QUIC_NO_ERROR) {
     std::string details =
         quiche::QuicheStrCat("Stream ", stream_->id(), ": ", error_details);
-    stream_->CloseConnectionWithDetails(read_error, details);
+    stream_->OnUnrecoverableError(read_error, details);
     return bytes_read;
   }
 
diff --git a/quic/core/quic_stream_sequencer.h b/quic/core/quic_stream_sequencer.h
index 0733664..42b583f 100644
--- a/quic/core/quic_stream_sequencer.h
+++ b/quic/core/quic_stream_sequencer.h
@@ -42,8 +42,8 @@
     virtual void Reset(QuicRstStreamErrorCode error) = 0;
     // Called when an error has occurred which should result in the connection
     // being closed.
-    virtual void CloseConnectionWithDetails(QuicErrorCode error,
-                                            const std::string& details) = 0;
+    virtual void OnUnrecoverableError(QuicErrorCode error,
+                                      const std::string& details) = 0;
 
     // Returns the stream id of this stream.
     virtual QuicStreamId id() const = 0;
diff --git a/quic/core/quic_stream_sequencer_test.cc b/quic/core/quic_stream_sequencer_test.cc
index 7cd498e..e2cd2ae 100644
--- a/quic/core/quic_stream_sequencer_test.cc
+++ b/quic/core/quic_stream_sequencer_test.cc
@@ -33,7 +33,7 @@
  public:
   MOCK_METHOD0(OnFinRead, void());
   MOCK_METHOD0(OnDataAvailable, void());
-  MOCK_METHOD2(CloseConnectionWithDetails,
+  MOCK_METHOD2(OnUnrecoverableError,
                void(QuicErrorCode error, const std::string& details));
   MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error));
   MOCK_METHOD0(OnCanWrite, void());
@@ -250,8 +250,7 @@
 }
 
 TEST_F(QuicStreamSequencerTest, EmptyFrame) {
-  EXPECT_CALL(stream_,
-              CloseConnectionWithDetails(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _));
+  EXPECT_CALL(stream_, OnUnrecoverableError(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _));
   OnFrame(0, "");
   EXPECT_EQ(0u, NumBufferedBytes());
   EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
@@ -375,7 +374,7 @@
   OnFinFrame(3, "");
   EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
 
-  EXPECT_CALL(stream_, CloseConnectionWithDetails(
+  EXPECT_CALL(stream_, OnUnrecoverableError(
                            QUIC_STREAM_SEQUENCER_INVALID_STATE,
                            "Stream 1 received new final offset: 1, which is "
                            "different from close offset: 3"));
@@ -612,8 +611,7 @@
   sequencer_->OnStreamFrame(frame1);
 
   QuicStreamFrame frame2(id, false, 2, quiche::QuicheStringPiece("hello"));
-  EXPECT_CALL(stream_,
-              CloseConnectionWithDetails(QUIC_OVERLAPPING_STREAM_DATA, _))
+  EXPECT_CALL(stream_, OnUnrecoverableError(QUIC_OVERLAPPING_STREAM_DATA, _))
       .Times(0);
   sequencer_->OnStreamFrame(frame2);
 }
@@ -751,7 +749,7 @@
 
 // Regression test for https://crbug.com/992486.
 TEST_F(QuicStreamSequencerTest, CorruptFinFrames) {
-  EXPECT_CALL(stream_, CloseConnectionWithDetails(
+  EXPECT_CALL(stream_, OnUnrecoverableError(
                            QUIC_STREAM_SEQUENCER_INVALID_STATE,
                            "Stream 1 received new final offset: 1, which is "
                            "different from close offset: 2"));
@@ -764,7 +762,7 @@
 // Regression test for crbug.com/1015693
 TEST_F(QuicStreamSequencerTest, ReceiveFinLessThanHighestOffset) {
   EXPECT_CALL(stream_, OnDataAvailable()).Times(1);
-  EXPECT_CALL(stream_, CloseConnectionWithDetails(
+  EXPECT_CALL(stream_, OnUnrecoverableError(
                            QUIC_STREAM_SEQUENCER_INVALID_STATE,
                            "Stream 1 received fin with offset: 0, which "
                            "reduces current highest offset: 3"));
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index 350a9ae..6f0bc4d 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -340,7 +340,7 @@
                                           const std::string& reason_phrase) {
   DCHECK(!reason_phrase.empty());
   state_ = STATE_CONNECTION_CLOSED;
-  stream()->CloseConnectionWithDetails(error, reason_phrase);
+  stream()->OnUnrecoverableError(error, reason_phrase);
 }
 
 void TlsClientHandshaker::FinishHandshake() {
diff --git a/quic/core/tls_handshaker_test.cc b/quic/core/tls_handshaker_test.cc
index 03a899f..59570b1 100644
--- a/quic/core/tls_handshaker_test.cc
+++ b/quic/core/tls_handshaker_test.cc
@@ -207,9 +207,8 @@
     for (size_t i = 0; i < pending_writes_.size(); ++i) {
       if (!stream->crypto_message_parser()->ProcessInput(
               pending_writes_[i].first, pending_writes_[i].second)) {
-        CloseConnectionWithDetails(
-            stream->crypto_message_parser()->error(),
-            stream->crypto_message_parser()->error_detail());
+        OnUnrecoverableError(stream->crypto_message_parser()->error(),
+                             stream->crypto_message_parser()->error_detail());
         break;
       }
     }
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index 3a99875..e5587cd 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -202,7 +202,7 @@
 void TlsServerHandshaker::CloseConnection(QuicErrorCode error,
                                           const std::string& reason_phrase) {
   state_ = STATE_CONNECTION_CLOSED;
-  stream()->CloseConnectionWithDetails(error, reason_phrase);
+  stream()->OnUnrecoverableError(error, reason_phrase);
 }
 
 bool TlsServerHandshaker::ProcessTransportParameters(