【问题标题】:UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'connect' of nullUnhandledPromiseRejectionWarning:TypeError:无法读取 null 的属性“连接”
【发布时间】:2020-02-07 04:31:55
【问题描述】:

我正在尝试连接到我的 Postgres 数据库,只是想看看我是否可以连接,我有一个条目。但是每当我尝试连接时,都会出现 connect null 错误,这是为什么呢?

我的数据库模型


    'use strict';

    import { Pool, Client } from 'pg';

    export default class Postgresql {

        private pool: Pool;

        constructor(private database: string, private host: string, private port: string, private user: string, private password: string) { };
        /* Create a PostgreSQL DB instance */
        connect = (): Promise<Pool> => new Promise((resolve, reject) => {
            this.pool = new Pool({
                database: this.database,
                host: this.host,
                port: Number(this.port),
                user: this.user,
                password: this.password
            });

            this.pool.connect().then(() => {
                resolve(this.pool);
            }).catch(err => reject(err));
        })

    }


我正在导入模型的数据库服务


    import Postgresql from "@root/src/app/models/database.model";

    const databaseService: {

        pool: Postgresql['pool'];
        init: () => Promise<string>;
        execute: (query: string, params: any, next?: any) => Promise<any>;
    } = {
        pool: null,
        init: () =>
            new Promise((resolve, reject) => {
                if (!databaseService.pool) new Postgresql(process.env.DATABASE, process.env.DATABASEHOST,
                    process.env.DATABASEPORT, process.env.DATABASEUSER, process.env.DATABASESECRET)
                    .connect()
                    .then((pool: Postgresql['pool']) => databaseService.pool = pool)
                    .catch((err: Error) => reject(err));
                resolve();
            }),
        async execute(query, params, next?) {
            let client = await this.pool.connect();
            try {
                const result = await client.query(query, params);
                console.log(result);
                next(null, result);
            } catch (e) {
                next(e, null);
            } finally {
                client.release();
            }
        }
    }

    export default databaseService;

从 server.js 调用数据库

        databaseService.init();
        let query = "SELECT * FROM ?";
        let params = "postgres"
        databaseService.execute(query, params);

和我的环境变量,我仔细检查了它们是否正确,但无论如何都是错误的。这是我第一次尝试使用 env var 连接到数据库,并通过服务进行,所以如果我做错了什么,请告诉我


    DATABASE=postgres
    DATABASEHOST=localhost
    DATABASEPORT=5432
    DATABASEUSER=postgres
    DATABASESECRET=password


    (node:11020) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'connect' of null
    at Object.<anonymous> (C:\Users\ENGU3002\Documents\Template\src\app\services\database.service.ts:20:38)
    at Generator.next (<anonymous>)
    at C:\Users\ENGU3002\Documents\Template\node_modules\tslib\tslib.js:110:75
    at new Promise (<anonymous>)
    at Object.__awaiter (C:\Users\ENGU3002\Documents\Template\node_modules\tslib\tslib.js:106:16)
    at Object.execute (C:\Users\ENGU3002\Documents\Template\src\app\services\database.service.ts:16:24)
    at C:\Users\ENGU3002\Documents\Template\src\app\server.ts:20:25
    at Generator.next (<anonymous>)
    at C:\Users\ENGU3002\Documents\Template\node_modules\tslib\tslib.js:110:75
    at new Promise (<anonymous>)
(node:11020) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:11020) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

【问题讨论】:

  • 确切的消息是什么以及报告错误的行是什么?一眼看去,我看不到 this.pool 在 databaseService 的任何地方被初始化。
  • 编辑帖子以显示错误代码,我把 databaseService.init();在 server.js 中创建实例

标签: node.js database postgresql typescript connection


【解决方案1】:

问题是您的 databaseService.init() 是异步的,但您并没有等待它,因此对 databaseService.execute 的调用发生在 init() 返回的承诺解决之前。

你要么需要打电话

await databaseService.init()

databaseService.init().then(....)

然后在 then 中进行查询。

与此没有直接关系,但如果您将函数声明为异步,则任何返回值都会自动包含在 Promise 中,因此您无需显式声明 Promise,这使代码更易于阅读并更容易发现诸如这个。例如 init 方法可能类似于:

init: async () => {
    if (!databaseService.pool) {
        databaseService.pool = await new Postgresql(
            process.env.DATABASE,
            process.env.DATABASEHOST,
            process.env.DATABASEPORT,
            process.env.DATABASEUSER,
            process.env.DATABASESECRET
        ).connect()
    }

【讨论】:

  • 这两个调用仍然在同一行给我一个错误,我确实将我的 init 方法更改为您提到的方式。我仍然习惯于使用 await 但这有助于我更多地理解它,谢谢。虽然 init 方法看起来有点不同,但 async 位于不同的位置。错误信息还是一样的
猜你喜欢
  • 2021-03-27
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
  • 2021-05-20
  • 2021-04-18
  • 2020-11-11
相关资源
最近更新 更多