[英]Unable to catch exception inside a Promise
I am trying to write a retry logic to connect to AWS Aurora db for mysql.我正在尝试为 mysql 编写重试逻辑以连接到 AWS Aurora db。 Aurora db can sleep if it is left idle for a specified amount of time and performs a cold restart upon receiving a request.
如果 Aurora db 在指定的时间内保持空闲状态,则可以休眠,并在收到请求后执行冷重启。 The restart can take 30-50sec and to establish a connection, I am doing three reattempts in the code below.
重新启动可能需要 30-50 秒并建立连接,我在下面的代码中重新尝试了 3 次。
To test the wait times on my local system, I am trying to simulate the sleep scenario by setting wrong port number when connection pool is being created.为了测试本地系统上的等待时间,我试图通过在创建连接池时设置错误的端口号来模拟睡眠场景。 And the code is throwing an error as expected.
并且代码按预期抛出错误。
Error: connect ECONNREFUSED 127.0.0.1:3305
(3306 is the correct one.) Error: connect ECONNREFUSED 127.0.0.1:3305
是正确的。)
{
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3305,
fatal: true
}
I invoke initConnection()
to create the pool and then use it to query the db.我调用
initConnection()
来创建池,然后使用它来查询数据库。 The code should throw the exception but it should throw it after 3 reattempts.代码应该抛出异常,但它应该在 3 次重试后抛出它。 But this is not happening.
但这并没有发生。 The code is throwing error when the code written for testing the connection is invoked.
当调用为测试连接而编写的代码时,代码会引发错误。 ('SHOW DATABASES;').
('显示数据库;')。 The code is not trying to reattempt the connection.
该代码不会尝试重新尝试连接。
Can someone help point out the issue in this code and how it can be corrected?有人可以帮助指出此代码中的问题以及如何纠正它吗?
const mysql = require("mysql");
export class DatabaseConnectionFactory {
private cPool: any;
private cPoolInit: boolean = false;
public async initConnection() {
try {
await this.createPool();
} catch (err) {
console.log(err);
}
}
private async createPool(attempt: number = 1) {
return new Promise(async (resolve, reject) => {
try {
if(!this.cPoolInit){
this.cPool = mysql.createPool({
connectionLimit: 500,
host:"mysqlHost",
port: "mysqlPort",
user: "mysqlUser",
password: "mysqlPassword"
});
// Test Connection
this.cPool.query('SHOW DATABASES;', null, (err, rows) => {
if (err){
throw err; // APP THROWS ERROR AT THIS LINE AND EXITS
}
console.log('Test Connection, Successful.');
});
this.cPoolInit = true;
}
resolve('Created Connection Pool.');
} catch(err) {
console.log(err);
console.log("Reattempting connection.");
await this.reattemptConnection(attempt);
reject('Unable to Create Connection Pool.');
}
});
}
private wait(seconds: number) {
const ms = 1000 * seconds;
return new Promise(resolve => setTimeout(resolve, ms));
}
private async reattemptConnection(reattempt: number) {
switch(reattempt) {
case 1: {
console.log('Reattempt 1');
await this.wait(30);
await this.createPool(reattempt + 1);
break;
}
case 2: {
console.log('Reattempt 2');
await this.wait(20);
await this.createPool(reattempt + 1);
break;
}
case 3: {
console.log('Reattempt 3');
await this.wait(10);
await this.createPool(reattempt + 1);
break;
}
default:{
break;
}
}
}
}
Not able to correctly test but something like this:无法正确测试,但类似这样:
// const mysql = require("mysql");
import * as mysql from "mysql";
export class DatabaseConnectionFactory {
private cPool: any;
private cPoolInit: boolean = false;
private testConnection(): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.cPool.query("SHOW DATABASES;", null, (err, rows) => {
if (err) {
reject(err);
} else {
console.log("Test Connection, Successful.");
resolve();
}
});
});
}
public async createPool(attempt: number = 0): Promise<void> {
if (this.cPoolInit) return;
try {
this.cPool = mysql.createPool({
connectionLimit: 500,
host: "mysqlHost",
port: 3305,
user: "mysqlUser",
password: "mysqlPassword"
});
await this.testConnection();
this.cPoolInit = true;
console.log("Created Connection Pool.");
} catch (err) {
console.log(err);
console.log("Reattempting connection.");
try {
await this.reattemptConnection(attempt);
} catch (e) {
throw new Error("Unable to Create Connection Pool.");
}
}
}
private wait(delayMs: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, delayMs));
}
private async reattemptConnection(reattempt: number) {
const delaysMs = [30 * 1000, 20 * 1000, 10 * 1000];
if (reattempt < 0 || reattempt >= delaysMs.length) {
throw new Error("Out of attempts");
}
console.log("Reattempt: " + reattempt.toString());
await this.wait(delaysMs[reattempt]);
await this.createPool(reattempt + 1);
}
}
All you had to do:所有你必须做的:
reject('Unable to Create Connection Pool.');
reject('Unable to Create Connection Pool.');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.