Skip to content

Commit 149226d

Browse files
authored
fix: backport postgres connection error handling to crdb (#10177)
1 parent 122b683 commit 149226d

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

src/driver/cockroachdb/CockroachQueryRunner.ts

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class CockroachQueryRunner
5555
/**
5656
* Special callback provided by a driver used to release a created connection.
5757
*/
58-
protected releaseCallback: Function
58+
protected releaseCallback?: (err: any) => void
5959

6060
/**
6161
* Stores all executed queries to be able to run them again if transaction fails.
@@ -105,7 +105,18 @@ export class CockroachQueryRunner
105105
.then(([connection, release]: any[]) => {
106106
this.driver.connectedQueryRunners.push(this)
107107
this.databaseConnection = connection
108-
this.releaseCallback = release
108+
109+
const onErrorCallback = (err: Error) =>
110+
this.releaseConnection(err)
111+
this.releaseCallback = (err?: Error) => {
112+
this.databaseConnection.removeListener(
113+
"error",
114+
onErrorCallback,
115+
)
116+
release(err)
117+
}
118+
this.databaseConnection.on("error", onErrorCallback)
119+
109120
return this.databaseConnection
110121
})
111122
} else {
@@ -115,7 +126,18 @@ export class CockroachQueryRunner
115126
.then(([connection, release]: any[]) => {
116127
this.driver.connectedQueryRunners.push(this)
117128
this.databaseConnection = connection
118-
this.releaseCallback = release
129+
130+
const onErrorCallback = (err: Error) =>
131+
this.releaseConnection(err)
132+
this.releaseCallback = (err?: Error) => {
133+
this.databaseConnection.removeListener(
134+
"error",
135+
onErrorCallback,
136+
)
137+
release(err)
138+
}
139+
this.databaseConnection.on("error", onErrorCallback)
140+
119141
return this.databaseConnection
120142
})
121143
}
@@ -124,21 +146,33 @@ export class CockroachQueryRunner
124146
}
125147

126148
/**
127-
* Releases used database connection.
128-
* You cannot use query runner methods once its released.
149+
* Release a connection back to the pool, optionally specifying an Error to release with.
150+
* Per pg-pool documentation this will prevent the pool from re-using the broken connection.
129151
*/
130-
release(): Promise<void> {
152+
private async releaseConnection(err?: Error) {
131153
if (this.isReleased) {
132-
return Promise.resolve()
154+
return
133155
}
134156

135157
this.isReleased = true
136-
if (this.releaseCallback) this.releaseCallback()
158+
if (this.releaseCallback) {
159+
this.releaseCallback(err)
160+
this.releaseCallback = undefined
161+
}
137162

138163
const index = this.driver.connectedQueryRunners.indexOf(this)
139-
if (index !== -1) this.driver.connectedQueryRunners.splice(index)
140164

141-
return Promise.resolve()
165+
if (index !== -1) {
166+
this.driver.connectedQueryRunners.splice(index, 1)
167+
}
168+
}
169+
170+
/**
171+
* Releases used database connection.
172+
* You cannot use query runner methods once its released.
173+
*/
174+
release(): Promise<void> {
175+
return this.releaseConnection()
142176
}
143177

144178
/**

0 commit comments

Comments
 (0)