in neqo-transport/src/connection/mod.rs [914:969]
fn capture_error<T>(
&mut self,
path: Option<PathRef>,
now: Instant,
frame_type: FrameType,
res: Res<T>,
) -> Res<T> {
if let Err(v) = &res {
#[cfg(debug_assertions)]
let msg = format!("{v:?}");
#[cfg(not(debug_assertions))]
let msg = "";
let error = CloseReason::Transport(v.clone());
match &self.state {
State::Closing { error: err, .. }
| State::Draining { error: err, .. }
| State::Closed(err) => {
qwarn!("[{self}] Closing again after error {err:?}");
}
State::Init => {
// We have not even sent anything just close the connection without sending any
// error. This may happen when client_start fails.
self.set_state(State::Closed(error), now);
}
State::WaitInitial | State::WaitVersion => {
// We don't have any state yet, so don't bother with
// the closing state, just send one CONNECTION_CLOSE.
if let Some(path) = path.or_else(|| self.paths.primary()) {
self.state_signaling
.close(path, error.clone(), frame_type, msg);
}
self.set_state(State::Closed(error), now);
}
_ => {
if let Some(path) = path.or_else(|| self.paths.primary()) {
self.state_signaling
.close(path, error.clone(), frame_type, msg);
if matches!(v, Error::KeysExhausted) {
self.set_state(State::Closed(error), now);
} else {
self.set_state(
State::Closing {
error,
timeout: self.get_closing_period_time(now),
},
now,
);
}
} else {
self.set_state(State::Closed(error), now);
}
}
}
}
res
}