|
7 | 7 | getBaseNodeChannel, |
8 | 8 | HttpErrorCode, |
9 | 9 | } from '@teable/core'; |
| 10 | +import type { Prisma } from '@teable/db-main-prisma'; |
10 | 11 | import { PrismaService } from '@teable/db-main-prisma'; |
11 | 12 | import type { |
12 | 13 | IBaseNodePresenceCreatePayload, |
@@ -174,6 +175,11 @@ export class BaseNodeService { |
174 | 175 | | IBaseNodePresenceDeletePayload, |
175 | 176 | >(baseId: string, handler: (presence: LocalPresence<T>) => void) { |
176 | 177 | this.performanceCacheService.del(generateBaseNodeListCacheKey(baseId)); |
| 178 | + // Skip if ShareDB connection is already closed (e.g., during shutdown) |
| 179 | + if (this.shareDbService.shareDbAdapter.closed) { |
| 180 | + this.logger.error('ShareDB connection is already closed, presence handler skipped'); |
| 181 | + return; |
| 182 | + } |
177 | 183 | const channel = getBaseNodeChannel(baseId); |
178 | 184 | const presence = this.shareDbService.connect().getPresence(channel); |
179 | 185 | const localPresence = presence.create(channel); |
@@ -1151,17 +1157,17 @@ export class BaseNodeService { |
1151 | 1157 | return; |
1152 | 1158 | } |
1153 | 1159 |
|
1154 | | - const deleteNode = async (prisma: PrismaService) => { |
| 1160 | + const deleteNode = async (prisma: Prisma.TransactionClient) => { |
1155 | 1161 | const toDeleteNode = await prisma.baseNode.findFirst({ |
1156 | 1162 | where: { baseId, resourceType, resourceId }, |
1157 | 1163 | }); |
1158 | 1164 | if (!toDeleteNode) { |
1159 | 1165 | return; |
1160 | 1166 | } |
1161 | | - const maxOrder = await this.getMaxOrder(baseId); |
1162 | | - await prisma.baseNode.delete({ |
| 1167 | + await prisma.baseNode.deleteMany({ |
1163 | 1168 | where: { id: toDeleteNode.id }, |
1164 | 1169 | }); |
| 1170 | + const maxOrder = await this.getMaxOrder(baseId); |
1165 | 1171 | const orphans = await prisma.baseNode.findMany({ |
1166 | 1172 | where: { baseId, parentId: toDeleteNode.parentId }, |
1167 | 1173 | select: { id: true, order: true }, |
|
0 commit comments