Skip to content

Commit 69ccfdf

Browse files
authored
Be resilient about a read after connection closed (#452)
fixes #449
1 parent e9b90b2 commit 69ccfdf

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

Sources/PostgresNIO/New/Connection State Machine/ConnectionStateMachine.swift

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -624,21 +624,19 @@ struct ConnectionStateMachine {
624624
mutating func readEventCaught() -> ConnectionAction {
625625
switch self.state {
626626
case .initialized:
627-
preconditionFailure("Received a read event on a connection that was never opened.")
628-
case .sslRequestSent:
629-
return .read
630-
case .sslNegotiated:
631-
return .read
632-
case .sslHandlerAdded:
633-
return .read
634-
case .waitingToStartAuthentication:
635-
return .read
636-
case .authenticating:
637-
return .read
638-
case .authenticated:
639-
return .read
640-
case .readyForQuery:
627+
preconditionFailure("Invalid state: \(self.state). Read event before connection established?")
628+
629+
case .sslRequestSent,
630+
.sslNegotiated,
631+
.sslHandlerAdded,
632+
.waitingToStartAuthentication,
633+
.authenticating,
634+
.authenticated,
635+
.readyForQuery,
636+
.closing:
637+
// all states in which we definitely want to make further forward progress...
641638
return .read
639+
642640
case .extendedQuery(var extendedQuery, let connectionContext):
643641
self.state = .modifying // avoid CoW
644642
let action = extendedQuery.readEventCaught()
@@ -651,12 +649,15 @@ struct ConnectionStateMachine {
651649
self.state = .closeCommand(closeState, connectionContext)
652650
return self.modify(with: action)
653651

654-
case .closing:
655-
return .read
656652
case .closed:
657-
preconditionFailure("How can we receive a read, if the connection is closed")
653+
// Generally we shouldn't see this event (read after connection closed?!).
654+
// But truth is, adopters run into this, again and again. So preconditioning here leads
655+
// to unnecessary crashes. So let's be resilient and just make more forward progress.
656+
// If we really care, we probably need to dive deep into PostgresNIO and SwiftNIO.
657+
return .read
658+
658659
case .modifying:
659-
preconditionFailure("Invalid state")
660+
preconditionFailure("Invalid state: \(self.state)")
660661
}
661662
}
662663

0 commit comments

Comments
 (0)