Skip to content

Deno - error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'replace') #778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bidipeppercrap opened this issue Jan 15, 2024 · 10 comments

Comments

@bidipeppercrap
Copy link

image
image

Spec

Runtime: Deno
Database Provider: Neon

Reproduce:

I run into this error when I try to migrate.

Code

deno.json

{
    "imports": {
        "db/": "./src/db/",
        "kysely": "npm:kysely@^0.27.2",
        "kysely-postgres-js": "npm:kysely-postgres-js@^2.0.0",
        "postgres": "https://deno.land/x/postgresjs@v3.4.3/mod.js"
    },
    "tasks": {
        "migrate": "deno run -A ./src/db/migrator.ts"
    }
}

migrator:

import * as path from "node:path";
import { fileURLToPath } from "node:url";
import { promises as fs } from "node:fs";
import { Migrator, FileMigrationProvider } from "kysely";
import { db } from "db/database.ts";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

async function migrateToLatest() {
    const migrator = new Migrator({
        db,
        provider: new FileMigrationProvider({
            fs,
            path,
            migrationFolder: path.join(__dirname, "./migrations")
        })
    });

    const { error, results } = await migrator.migrateToLatest();

    results?.forEach((it) => {
        if (it.status === "Success") {
            console.log(`migration "${it.migrationName}" was executed successfully`);
        } else if (it.status === "Error") {
            console.error(`failed to execute migration "${it.migrationName}"`);
        }
    });

    if (error) {
        console.error("failed to migrate");
        console.error(error);
        Deno.exit(1);
    }

    await db.destroy();
}

migrateToLatest();

db instance:

import { Database } from "db/types/index.ts";
import postgres from "postgres";
import { Kysely } from "kysely";
import { PostgresJSDialect } from "kysely-postgres-js";
import { load } from "https://deno.land/std@0.212.0/dotenv/mod.ts";

const env = await load();

const dialect = new PostgresJSDialect({
    postgres: postgres({
        database: env["PGDATABASE"]!,
        host: env["PGHOST"]!,
        user: env["PGUSER"]!,
        password: env["PGPASSWORD"]!,
        port: 5434,
        max: 10,
    })
});

export const db = new Kysely<Database>({
    dialect
});
@skelawsky
Copy link

Have you found solution?

@lpite
Copy link

lpite commented Mar 1, 2024

Same problem with nextjs node or bun doesn't matter

@bidipeppercrap
Copy link
Author

bidipeppercrap commented Mar 1, 2024

Same problem with nextjs node or bun doesn't matter

I found it worked with Node

Only in Deno it is not working.

@lpite
Copy link

lpite commented Mar 1, 2024

Same problem with nextjs node or bun doesn't matter

I found it worked with Next.js Typescript

Only in Deno it is not working.

It's working in production I guess but on dev it can work for a while but then on hot reload this error happens

@bidipeppercrap
Copy link
Author

Same problem with nextjs node or bun doesn't matter

I found it worked with Next.js Typescript
Only in Deno it is not working.

It's working in production I guess but on dev it can work for a while but then on hot reload this error happens

This is a matter of migrating
It worked with Node or npm run migrate...
But doesn't work with deno task migrate...

@divmgl
Copy link

divmgl commented Mar 5, 2024

I'm having this issue when reserving but not with regular connections. @porsager could really use your help here.

const admin = pg(databaseUrl, { database: "postgres" })

return {
  admin: await admin.reserve()
}

Crashes:

node_modules/.pnpm/postgres@3.4.3/node_modules/postgres/src/connection.js:389
      stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
                                               ^

TypeError: Cannot read properties of undefined (reading 'replace')

Heads up that doing

await admin.unsafe("SELECT 1")

Solved the issue for me.

@episage
Copy link

episage commented Mar 6, 2024

The problem occurs when I open my Mac after a couple of hours. This is a bug in error handling routine and obscures the real error. 100% should be fixed in this package.

file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:389
      stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
                                               ^

TypeError: Cannot read properties of undefined (reading 'replace')
    at queryError (file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:389:48)
    at errored (file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:383:14)
    at Socket.data (file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:318:9)
    at Socket.emit (node:events:514:28)
    at Socket.emit (node:domain:488:12)
    at addChunk (node:internal/streams/readable:376:12)
    at readableAddChunk (node:internal/streams/readable:349:9)
    at Readable.push (node:internal/streams/readable:286:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23)

Node.js v20.9.0
npm ERR! Lifecycle script `dev` failed with error: 
npm ERR! Error: command failed 
npm ERR!   in workspace: backend@1.0.0 
npm ERR!   at location: /Users/epi/projects/hs4/packages/backend 

@episage
Copy link

episage commented Mar 12, 2024

Found the offending line:

image
Query:
{
  reserve: [Function (anonymous)],
  state: { pid: 17618, secret: 131674580 },
  active: true
}
Error:
TypeError: Cannot read properties of undefined (reading '0')
    at build (file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:223:42)
    at execute (file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:167:7)
    at ReadyForQuery (file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:568:27)
    at handle (file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:503:6)
    at Socket.data (file:///Users/epi/projects/hs4/node_modules/postgres/src/connection.js:315:9)
    at Socket.emit (node:events:514:28)
    at Socket.emit (node:domain:488:12)
    at addChunk (node:internal/streams/readable:376:12)
    at readableAddChunk (node:internal/streams/readable:349:9)
    at Readable.push (node:internal/streams/readable:286:10)

@coder-se
Copy link

coder-se commented Jun 7, 2024

We saw this issue as well in our production environments after starting to use kysely-postgres-js.

We managed to track it down to the fact that initial is sometimes set to true and sometime to a query, it also seems to be true more frequently when reserving connections using reserve(). This is what kysely-postgres-js does under the hood, and also when @divmgl saw it. The current "workaround" is to use the suggestion from @divmgl and add a await sql.unsafe('SELECT 1') before the connection is reserved. By doing this we get the actual error message.

The minimal code to reproduce this issue is to run the code below while your postgres instance is shutting down;

    const sql = postgres({
        ...
    });
    const reserved = await sql.reserve();
    await reserved.unsafe('SELECT 1');

initial could potentially be set to true here;

postgres/src/connection.js

Lines 108 to 114 in f58cd4f

const connection = {
queue: queues.closed,
idleTimer,
connect(query) {
initial = query || true
reconnect()
},

But expected to be a query here;

postgres/src/connection.js

Lines 384 to 397 in f58cd4f

initial && (queryError(initial, err), initial = null)
}
function queryError(query, err) {
Object.defineProperties(err, {
stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
query: { value: query.string, enumerable: options.debug },
parameters: { value: query.parameters, enumerable: options.debug },
args: { value: query.args, enumerable: options.debug },
types: { value: query.statement && query.statement.types, enumerable: options.debug }
})
query.reject(err)
}

When running the reproduction code above, we could see that query=true in queryError(query, err) { ... }

@episage
Copy link

episage commented Jun 15, 2024

To replicate the problem:

  1. Turn off your SQL server.
  2. Use .reserve().

The error is shadowed with another one throwing in postgres/src/connection.js because query is true instead of actual query.

 + query.origin.replace(/.*\n/, '\n')
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants