kysely icon indicating copy to clipboard operation
kysely copied to clipboard

Connection hanging after executing another query

Open lucastonelli opened this issue 5 months ago • 2 comments

Hey there! 👋🏻.

I've started using Kysely recently after using Django for quite some time and I found it to be quite nice, thanks! However, I'm having problems when executing queries.

I'm trying to execute two queries in a row:


export class BlogService {
  #apiKey;
  #db;

  constructor(config: { apiKey?: string; db: Kysely<DB> }) {
    const { apiKey, db } = config;

    if (!apiKey) {
      throw new Error("API key not present");
    }

    this.#apiKey = apiKey;
    this.#db = db;
  }

  #getApiKeyHash({ apiKey }: { apiKey: string }) {
    return createHash("sha256").update(apiKey).digest("base64url");
  }

  async #getTenant({ apiKey }: { apiKey: string }) {
    return await this.#db
      .selectFrom("Tenant")
      .innerJoin("ApiKey", "ApiKey.tenantId", "Tenant.id")
      .select("Tenant.id")
      .where("ApiKey.key", "=", this.#getApiKeyHash({ apiKey }))
      .executeTakeFirst();
  }

  async #getOrCreateTenant({ apiKey }: { apiKey: string }) {
    const tenant = await this.#getTenant({ apiKey });

    if (tenant) {
      return tenant;
    }

    return await this.#db
      .with("tenantCte", (db) => {
        return db
          .insertInto("Tenant")
          .values({ uuid: randomUUID() })
          .returning("id");
      })
      .insertInto("ApiKey")
      .values(({ selectFrom }) => ({
        key: this.#getApiKeyHash({ apiKey }),
        uuid: randomUUID(),
        tenantId: selectFrom("tenantCte").select("tenantCte.id"),
      }))
      .returning("id")
      .executeTakeFirstOrThrow();
  }

  async createPost(payload: CreatePostProps) {
    if (!payload) {
      throw new MalformedResourceError({ resource: "request", name: "body" });
    }

    const parsedPayload = JSON.parse(payload);

    const tenant = await this.#getOrCreateTenant({
      apiKey: this.#apiKey,
    });

    return await this.#db
      .insertInto("Post")
      .values({ ...parsedPayload, tenantId: tenant.id })
      .returning("uuid")
      .executeTakeFirstOrThrow();
  }
}

When calling createPost the function #getTenant is called and returns the tenant (or undefined), but when the CTE is called, the connection hangs, as long as the test timeout . I've replaced the CTE query for the #getTenant call and it hangs anyway. The log I get is the following:

  console.log
    kysely:query: select "Tenant"."id" from "Tenant" inner join "ApiKey" on "ApiKey"."tenantId" = "Tenant"."id" where "ApiKey"."key" = $1

      at Log.defaultLogger (node_modules/kysely/dist/cjs/util/log.js:43:17)

  console.log
    kysely:query: duration: 0.0ms

      at Log.defaultLogger (node_modules/kysely/dist/cjs/util/log.js:44:17)

My db setup is as follow:

import { Kysely, PostgresDialect } from "kysely";
import type { DB } from "kysely-codegen";
import { Pool } from "pg";

export const db = new Kysely<DB>({
  dialect: new PostgresDialect({
    pool: new Pool({
      connectionString: process.env.DATABASE_URL,
    }),
  }),
  log: ["query", "error"],
});

What am I getting wrong?

lucastonelli avatar Jun 18 '25 01:06 lucastonelli

I can't see anything wrong in your setup or code that could cause this.

koskimas avatar Jun 18 '25 05:06 koskimas

Are you sure something doesn't throw and you're just ignoring the exception? Maybe you're missing await somewhere?

koskimas avatar Jun 18 '25 06:06 koskimas

Hey 👋

Can you share a reproduction repository?

igalklebanov avatar Jun 18 '25 11:06 igalklebanov

Thanks for the quick reply, people.

Are you sure something doesn't throw and you're just ignoring the exception? Maybe you're missing await somewhere?

@koskimas, I reviewed that and even asked Claude for some help, but there's nothing of sort wrong 😆

Hey 👋 Can you share a reproduction repository?

I'll set up a reproduction repository and send here.

lucastonelli avatar Jun 18 '25 12:06 lucastonelli

I've set up a small reproduction and it's working fine. I'll close this and work on what might be the problem. Thanks!

lucastonelli avatar Jun 18 '25 12:06 lucastonelli

@koskimas and @igalklebanov, I saw someplace about an issue with Jest and after migrating to vitest it was fixed, so I did the same and it fixed the problem. Just to let you know!

lucastonelli avatar Jun 18 '25 19:06 lucastonelli