Skip to content

Commit bcd6957

Browse files
committed
fix(database): The problem of connecting to the database has been solved, and if it fails once, it tries several times to connect
1 parent 93c32be commit bcd6957

File tree

10 files changed

+45
-34
lines changed

10 files changed

+45
-34
lines changed

src/bot/service/admin/Ban.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export class BanService {
1919
// Remove the user from the group's approved_users and members arrays
2020
const updatedGroup = {
2121
...group,
22-
approved_users: group.approved_users.filter((id) => Number(id) !== userId),
23-
members: group.members.filter((id) => Number(id) !== userId),
22+
approved_users: group.approved_users.filter((id: number) => Number(id) !== userId),
23+
members: group.members.filter((id: number) => Number(id) !== userId),
2424
};
2525
await groupService.update(updatedGroup);
2626
await userService.delete(userId);

src/bot/service/admin/Blacklist.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class BlackListService {
5353
}
5454
} else {
5555
// Remove the specified word
56-
group.black_list = group.black_list.filter((item) => item !== word);
56+
group.black_list = group.black_list.filter((item:string) => item !== word);
5757
}
5858
await groupService.update({
5959
...group,

src/bot/service/admin/Warn.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class WarnService {
5050
// Reset the warnings count and clear the user from the group's warning list
5151
const updatedGroup = {
5252
...group,
53-
warnings: group.warnings.filter((id) => Number(id) !== Number(user.telegram_id)),
53+
warnings: group.warnings.filter((id: number) => Number(id) !== Number(user.telegram_id)),
5454
};
5555
const updatedUser = {
5656
...user,
@@ -109,6 +109,8 @@ export class WarnService {
109109
const userId = replyMessage!.id!;
110110
const chat = ctx.chat;
111111
const groupId = chat?.id!;
112+
113+
// Initialize services
112114
const services = ServiceProvider.getInstance();
113115
const [groupService, userService, warnService] = await Promise.all([services.getGroupService(), services.getUserService(), services.getWarnsService()]);
114116
let group = await groupService.getByGroupId(groupId);
@@ -138,6 +140,7 @@ export class WarnService {
138140
});
139141
}
140142
}
143+
console.log('usersWithWarnings', JSON.stringify(usersWithWarnings, null, 2));
141144

142145
// Generate structured output
143146
let output = `**Group Warning Report**\n`;
@@ -150,8 +153,6 @@ export class WarnService {
150153
output += ` Warnings: ${user.warnings}\n`;
151154
output += ` Last Reason: ${user.reason}\n`;
152155
});
153-
154-
// Add summary
155156
output += `\n---\nTotal Users with Warnings: ${usersWithWarnings.length}\n`;
156157

157158
return output;

src/database/ConnectionPool.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,6 @@ export class ConnectionPool {
4747
try {
4848
await client.query(`CREATE DATABASE "${databaseName}"`);
4949
console.log(`Database "${databaseName}" created successfully.`);
50-
} catch (error: any) {
51-
console.error('Failed to create database:', error.message);
52-
throw error; // Re-throw the error for better logging and troubleshooting
5350
} finally {
5451
await client.end();
5552
}
@@ -69,9 +66,10 @@ export class ConnectionPool {
6966
return new Pool({
7067
connectionString,
7168
ssl: this._isProduction === 'production' ? { rejectUnauthorized: false } : false,
72-
connectionTimeoutMillis: 60000,
73-
max: 15,
74-
idleTimeoutMillis: 60000,
69+
max: 20,
70+
idleTimeoutMillis: 30000,
71+
connectionTimeoutMillis: 30000,
72+
keepAlive: true,
7573
});
7674
}
7775
private async reinitializePool() {

src/decorators/Bot.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ export function ReplyToBot() {
2424
close();
2525
return;
2626
}
27-
return next();
27+
await next();
2828
});
2929
}

src/decorators/Catch.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export function Catch(customResponse?: ErrorResponse) {
66
return createDecorator(async (ctx, next) => {
77
try {
88
await next();
9+
return;
910
} catch (error: any) {
1011
if (isGrammyError(error)) {
1112
if (error.error_code === 400 && error.description === 'Bad Request: message to be replied not found') {

src/decorators/Context.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { BotReply } from '../utils/chat/BotReply';
22
import { MessagesService } from '../service/messages';
3-
import { RateLimitConfig } from '../types/CommandTypes';
43
import { createDecorator } from './index';
54
/**
65
* A decorator to restrict commands to group chats.
@@ -14,7 +13,6 @@ export function RestrictToGroupChats() {
1413
try {
1514
if (chat.type === 'supergroup' || chat.type === 'group') {
1615
await next();
17-
return;
1816
} else if (chat.type === 'private') {
1917
await reply.textReply('This command can only be used in group chats.');
2018
close();

src/decorators/Database.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ export function EnsureUserAndGroup(userSource: 'from' | 'reply' = 'reply') {
2626
return createDecorator(async (ctx: Context, next, close) => {
2727
try {
2828
const service = ServiceProvider.getInstance();
29-
const userService = await service.getUserService();
30-
const groupService = await service.getGroupService();
3129
const userContext = userSource === 'reply' && ctx.message?.reply_to_message?.from && !ctx.message.reply_to_message.forum_topic_created ? ctx.message.reply_to_message.from : ctx.from;
3230
const userId = userContext?.id;
3331
const groupId = ctx.chat?.id;
@@ -41,14 +39,7 @@ export function EnsureUserAndGroup(userSource: 'from' | 'reply' = 'reply') {
4139
id: userId,
4240
username: userContext!.username!,
4341
};
44-
let user = await userService.getByTelegramId(userId);
45-
if (!user) {
46-
user = await userService.save(userData);
47-
}
48-
let group = await groupService.getByGroupId(groupId);
49-
if (!group) {
50-
group = await groupService.save(ctx);
51-
}
42+
await Promise.all([service.getUserService().then((userService) => userService.save(userData)), service.getGroupService().then((groupService) => groupService.save(ctx))]);
5243
await next();
5344
} catch (error) {
5445
console.error('Error in EnsureUserAndGroup decorator:', error);

src/service/database/ServiceProvider.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { GroupService } from '../../database/models/Group';
55
import { UserService } from '../../database/models/User';
66
import { GroupRuleService } from '../../database/models/GroupRule';
77
import { WarningDatabaseService } from '../../database/models/Warning';
8+
import logger from '../../utils/logger';
89

910
export class ServiceProvider {
1011
private static instance: ServiceProvider;
@@ -40,20 +41,28 @@ export class ServiceProvider {
4041
return await this._connectionPool.getClient();
4142
}
4243
async getGroupService() {
43-
const client = await this.getPoolClint();
44-
return new GroupService(client);
44+
return await this.retryConnect(async () => {
45+
const client = await this.getPoolClint();
46+
return new GroupService(client);
47+
});
4548
}
4649
async getUserService() {
47-
const client = await this.getPoolClint();
48-
return new UserService(client);
50+
return await this.retryConnect(async () => {
51+
const client = await this.getPoolClint();
52+
return new UserService(client);
53+
});
4954
}
5055
async getRulesService() {
51-
const client = await this.getPoolClint();
52-
return new GroupRuleService(client);
56+
return await this.retryConnect(async () => {
57+
const client = await this.getPoolClint();
58+
return new GroupRuleService(client);
59+
});
5360
}
5461
async getWarnsService() {
55-
const clint = await this.getPoolClint();
56-
return new WarningDatabaseService(clint);
62+
return await this.retryConnect(async () => {
63+
const clint = await this.getPoolClint();
64+
return new WarningDatabaseService(clint);
65+
});
5766
}
5867
async healthCheck(): Promise<boolean> {
5968
try {
@@ -67,4 +76,17 @@ export class ServiceProvider {
6776
return false;
6877
}
6978
}
79+
private async retryConnect(fn: Function, retries = 3, delay = 5000) {
80+
for (let attempt = 0; attempt < retries; attempt++) {
81+
try {
82+
return await fn();
83+
} catch (error: any) {
84+
logger.error(`Database Retry Attempt ${attempt + 1}: ${error.message}`, 'Database');
85+
if (attempt < retries - 1) {
86+
await new Promise((res) => setTimeout(res, delay));
87+
}
88+
}
89+
}
90+
throw new Error('Failed to connect to the database after retries');
91+
}
7092
}

src/service/messages/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class MessagesService {
9090
return;
9191
}
9292
const blacklist = group.black_list;
93-
const isForbidden = blacklist.some((word) => {
93+
const isForbidden = blacklist.some((word: string) => {
9494
const regex = new RegExp(`(^|\\s)${word}($|\\s|[.,!?;])`, 'i'); // \b is a word boundary, 'i' is for case-insensitive matching
9595
return regex.test(messageText);
9696
});

0 commit comments

Comments
 (0)