PgClient: withTransaction dies instead of failing with SqlError when the server ends the session
メンテナーはふだん 1 日以内に返信
評価
この issue はまだ評価されていません。
説明
What version of Effect is running?
[email protected], @effect/[email protected], PostgreSQL 14, Node 26.3.1. Reproduced on main (506eef1).
What steps can reproduce the bug?
When the server ends the session inside withTransaction (pg_terminate_backend, an administrator's kill, idle_in_transaction_session_timeout, a dropped connection), the statement fails with a typed SqlError. The server has already rolled the transaction back with the session. withTransaction then issues its own ROLLBACK on the closed connection, which can only fail, and that error is added to the exit as a defect.
import { PgClient } from "@effect/sql-pg"
import { Effect, Redacted } from "effect"
import * as Reactivity from "effect/reactivity/Reactivity"
const program = Effect.gen(function*() {
const sql = yield* PgClient.make({ url: Redacted.make("postgres://postgres:postgres@localhost:5432/postgres") })
const exit = yield* Effect.exit(sql.withTransaction(sql`SELECT pg_terminate_backend(pg_backend_pid())`))
for (const r of exit._tag === "Failure" ? exit.cause.reasons : []) {
const e = r._tag === "Fail" ? r.error : r._tag === "Die" ? r.defect : undefined
console.log(`${r._tag}: ${e?.reason?._tag} ${e?.reason?.cause?.message}`)
}
const recovered = yield* sql.withTransaction(sql`SELECT pg_terminate_backend(pg_backend_pid())`).pipe(
Effect.as("not reached"),
Effect.catchTag("SqlError", () => Effect.succeed("recovered")),
Effect.catchDefect(() => Effect.succeed("died"))
)
console.log(`catchTag("SqlError"): ${recovered}`)
})
Effect.runPromise(Effect.scoped(program).pipe(Effect.provide(Reactivity.layer)))
Die: UnknownError terminating connection due to administrator command
Die: ConnectionError Connection closed
catchTag("SqlError"): died
What is the expected behavior?
The exit fails with the statement's SqlError only, and Effect.catchTag("SqlError", ...) recovers. With PgClient's pool, the next transaction runs on a fresh session.
What do you see instead?
The ROLLBACK failure is a defect. Since #9433 it takes precedence over the body's typed failure, so the exit is Die(UnknownError) + Die(ConnectionError), catchTag("SqlError", ...) no longer runs, and the transaction dies even when the caller handles SqlError. A nested withTransaction fails the same way at ROLLBACK TO SAVEPOINT.
Additional information
This is the PostgreSQL side of #9586. On failure, makeWithTransaction runs Effect.orDie over the rollback and savepoint cleanup (SqlClient.ts#L699-L709). #9599 added an isTransaction predicate to SqlClient.make that skips that cleanup once no transaction is open (#L317-L334), but only the SQLite clients pass it. PgClient does not (PgClient.ts#L314-L334).
The connection already tracks what the predicate needs: deadWith and transactionStatus, updated from each ReadyForQuery (PgConnection.ts#L392-L396, #L455). The public PgConnection interface exposes neither (#L213).
Fix idea: expose PgConnection.inTransaction (false once the session has ended) and pass isTransaction from PgClient. A ROLLBACK on a live session, aborted or not, still runs, and its failures stay defects.
- 主要言語
- TypeScript
- スター
- 16.7k
- フォーク
- 808
- 平均マージ
- 12時間 16分
- マージ済み PR(30日)
- 809
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
Effect-TS/effect のほかの issue
-
McpServer.layerHttp: optional legacy GET SSE for idle list-change notifications対応中かも @effect-bot が 1 日前に担当しました。 オープン
Effect-TS/effect#10436 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
SqlClient: a fiber forked inside a transaction keeps using its connection after the transaction ends対応中かも @effect-bot が 1 日前に担当しました。 オープンbug
Effect-TS/effect#10431 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
CLI completions stop offering repeatable flags after their first use対応中かも @effect-bot が 1 日前に担当しました。 オープン
Effect-TS/effect#10427 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
sql-pg: pgvector columns fail with "Invalid UTF-8 in text value"対応中かも @effect-bot が 2 日前に担当しました。 オープンbug
Effect-TS/effect#10420 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
cli: completions break for subcommand names with `:`対応中かも @effect-bot が 2 日前に担当しました。 オープン
Effect-TS/effect#10416 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
Effect-TS/effect の issue をすべて見る
似ている issue
-
area:cards enhancement ready-for-agent
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
fil-donadoni/tolaria#8883 ·
メンテナーはふだん 1 日以内に返信
-
xsd:integer cast from a string rejects negative numbers, a leading + and surrounding whitespaceオープンbug 🐛
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
comunica/comunica#1960 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Waiting for: Product Owner
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
getsentry/sentry-javascript#26203 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
bytedance/flowgram.ai#1235 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
devswha/herdr-web-ui#3325 ·