You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL短链接API报错:Cannot read properties of undefined (reading 'postgresClient')

问题分析与解决

核心问题1:类方法的this绑定丢失

当你把post方法作为Express路由处理函数时,默认情况下this不会指向ShortController的实例,导致this.postgreClient变成undefined。

解决方法(三选一)

方法1:构造函数内绑定this

修改ShortController的构造函数,手动绑定post方法的this:

import { Request, Response, NextFunction } from "express";
import client from "../Database";

export default class ShortController {
    private postgreClient;

    constructor() {
        this.postgreClient = client;
        // 绑定this到post方法
        this.post = this.post.bind(this);
    }

    async post(request: Request, response: Response, next: NextFunction) {
        // ... 原有代码逻辑
    }
}

方法2:使用箭头函数定义方法

箭头函数会自动捕获当前上下文的this,避免绑定问题:

import { Request, Response, NextFunction } from "express";
import client from "../Database";

export default class ShortController {
    private postgreClient;

    constructor() {
        this.postgreClient = client;
    }

    // 用箭头函数定义post方法
    post = async (request: Request, response: Response, next: NextFunction) => {
        const url = request.query.url;
        const randomString = Math.random().toString(36).substring(2, 7);

        const shortUrl = `${process.env.API_URL}/api/short/${randomString}`;

        try {
            const sql = "INSERT INTO short (short_url, url) VALUES ($1, $2)";
            await this.postgreClient.query(sql, [shortUrl, url]);
            response.json({ shortUrl });
        } catch (exception) {
            console.error(exception);
            response.json({ message: "Error" });
        }
    }
}

方法3:路由配置时绑定this

如果你的路由是这样注册的:

const controller = new ShortController();
app.post('/api/short', controller.post);

改成手动绑定:

app.post('/api/short', controller.post.bind(controller));

核心问题2:数据库客户端未建立连接

你的Database.ts里只创建了Client实例,但没有调用connect()方法建立连接,即便postgreClient不是undefined,后续查询也会报错。

解决方法:添加连接逻辑

修改Database.ts,确保客户端连接到数据库:

import { Client } from "pg";
import * as dotenv from "dotenv";

dotenv.config();

const dbHost = process.env.DB_HOST || "localhost";
const dbPort = process.env.DB_PORT || 5432;
const dbUser = process.env.DB_USER || "postgres";
const dbPassword = process.env.DB_PASSWORD || "password";
const dbDatabase = process.env.DB_DATABASE || "kyowakoku";

const connectionString = `postgres://${dbUser}:${dbPassword}@${dbHost}:${dbPort}/${dbDatabase}`;

const client = new Client({ connectionString });

// 立即建立连接并添加错误处理
client.connect()
    .then(() => console.log("数据库连接成功"))
    .catch(err => console.error("数据库连接失败:", err));

export default client;

另外,建议在启动Express服务前等待数据库连接完成,避免启动时就报错:
比如在入口文件(如app.ts)里:

import client from './Database';
import express from 'express';

const app = express();

// 等待数据库连接成功后再启动服务
client.connect()
    .then(() => {
        app.listen(3000, () => {
            console.log("服务启动在3000端口");
        });
    })
    .catch(err => {
        console.error("无法启动服务:数据库连接失败", err);
        process.exit(1);
    });

额外注意点

  • 确保.env文件配置正确,所有数据库相关环境变量已正确设置
  • 检查short表是否已在数据库中创建,结构符合short_url和url字段的要求

内容的提问来源于stack exchange,提问作者sech1p

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 23:25:33