denodrivers / postgres

PostgreSQL driver for Deno

Home Page:https://denodrivers.github.io/postgres

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Prepared statement error in transactions

malj opened this issue · comments

  • deno-postgres 0.12.0
  • deno 1.14.0
  • psql 12.8
  • ubuntu 20.04.1 (WSL2)

Problem

Invalid prepared statements fail in transactions with an unexpected generic error Unexpected frame: Z, and client doesn't get unlocked.

Expectation

Return PostgresError (as would an equivalent query outside of transaction) or TransactionError instead of the generic error, and unlock the client.

Example

import { Client } from "https://deno.land/x/postgres@v0.12.0/mod.ts"
import { PostgresError, TransactionError } from "https://deno.land/x/postgres@v0.12.0/connection/warning.ts"

const client = new Client({ ... })

await client.queryArray`create table if not exists example (n int)`

const transaction = client.createTransaction("t")

try {
    await transaction.begin()
    await transaction.queryArray("insert into example (n) values ($1)", "text")
    await transaction.commit()
} catch (error) {
    console.log(error) // Error: Unexpected frame: Z (stack trace below)
    console.log(error instanceof PostgresError) // false
    console.log(error instanceof TransactionError) // false
}

try {
    await client.queryArray`select * from example`
} catch (error) {
    console.log(error) // Error: This connection is currently locked by the "t" transaction
}

await client.end()
Error: Unexpected frame: Z
    at Connection.#simpleQuery (https://deno.land/x/postgres@v0.12.0/connection/connection.ts:681:15)
    at async Connection.query (https://deno.land/x/postgres@v0.12.0/connection/connection.ts:920:16)
    at async Transaction.queryArray (https://deno.land/x/postgres@v0.12.0/query/transaction.ts:354:14)
    at async Transaction.commit (https://deno.land/x/postgres@v0.12.0/query/transaction.ts:247:7)
    at async Transaction.queryArray (https://deno.land/x/postgres@v0.12.0/query/transaction.ts:359:9)

Use case

I'm building a REST API, and using pooled connections. Failed transactions leave the reusable connection in an errored state causing issues for other requests, and the unexpected error type means that clients get a wrong HTTP response status (500 instead of 4xx).

Thank you @malj, that specific test case finally made me locate the cause of this bug that had been driving me crazy. Already patched

Hi @Soremwar, thank you for such a quick response! I've tested the patched version and the transaction issue seems to be fixed.

However, I think I've run across a similar issue when executing multiple invalid prepared statements outside of transactions. I've created a new issue for it: #322