forked from mirrors/misskey
fix(backend): route fastify listen/ready/close errors through logger instead of unhandled rejection (#17401)
* fix(backend): route fastify listen/ready/close errors through logger instead of unhandled rejection * Update CHANGELOG.md --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
parent
dc96c35296
commit
b125ce1eb2
2 changed files with 30 additions and 18 deletions
|
|
@ -28,6 +28,7 @@
|
|||
- Fix: PerUserDriveChart がシステム所有ファイル (userId が null) の更新で `"group"` の非NULL制約違反によりクラッシュする問題を修正 (#17498)
|
||||
- Fix: センシティブメディア自動検出周りの依存関係・ファイルの解決に失敗する問題を修正
|
||||
- Fix: フォロワー限定投稿を指名投稿で引用した際に、引用した投稿の公開範囲が意図せず変更される問題を修正
|
||||
- Fix: Startup and shutdown failures (port-in-use, socket permission denied, plugin timeouts, leaked WebSocket connections) are now reported through the misskey logger instead of an UnhandledPromiseRejectionWarning stack trace
|
||||
|
||||
## 2026.5.4
|
||||
|
||||
|
|
|
|||
|
|
@ -242,16 +242,16 @@ export class ServerService implements OnApplicationShutdown {
|
|||
|
||||
this.streamingApiServerService.attach(fastify.server);
|
||||
|
||||
fastify.server.on('error', err => {
|
||||
switch ((err as any).code) {
|
||||
const handleListenError = (err: unknown): void => {
|
||||
switch ((err as NodeJS.ErrnoException).code) {
|
||||
case 'EACCES':
|
||||
this.logger.error(`You do not have permission to listen on port ${this.config.port}.`);
|
||||
this.logger.error(`You do not have permission to listen on ${this.config.socket ?? `port ${this.config.port}`}.`);
|
||||
break;
|
||||
case 'EADDRINUSE':
|
||||
this.logger.error(`Port ${this.config.port} is already in use by another process.`);
|
||||
this.logger.error(`${this.config.socket ?? `Port ${this.config.port}`} is already in use by another process.`);
|
||||
break;
|
||||
default:
|
||||
this.logger.error(err);
|
||||
this.logger.error(err as Error);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -261,28 +261,39 @@ export class ServerService implements OnApplicationShutdown {
|
|||
// disableClustering
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (this.config.socket) {
|
||||
if (fs.existsSync(this.config.socket)) {
|
||||
fs.unlinkSync(this.config.socket);
|
||||
}
|
||||
fastify.listen({ path: this.config.socket }, (err, address) => {
|
||||
if (this.config.chmodSocket) {
|
||||
fs.chmodSync(this.config.socket!, this.config.chmodSocket);
|
||||
try {
|
||||
if (this.config.socket) {
|
||||
if (fs.existsSync(this.config.socket)) {
|
||||
fs.unlinkSync(this.config.socket);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fastify.listen({ port: this.config.port, host: '0.0.0.0' });
|
||||
await fastify.listen({ path: this.config.socket });
|
||||
if (this.config.chmodSocket) {
|
||||
fs.chmodSync(this.config.socket, this.config.chmodSocket);
|
||||
}
|
||||
} else {
|
||||
await fastify.listen({ port: this.config.port, host: '0.0.0.0' });
|
||||
}
|
||||
await fastify.ready();
|
||||
} catch (err) {
|
||||
handleListenError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
await fastify.ready();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async dispose(): Promise<void> {
|
||||
await this.streamingApiServerService.detach();
|
||||
await this.#fastify.close();
|
||||
// fastify@5 close() waits for upgraded WebSocket connections to drain.
|
||||
// streamingApiServerService.attach() adds raw ws.Server upgrades that
|
||||
// fastify does not track in its connection registry, so close() can hang
|
||||
// forever during OnApplicationShutdown. Cap at 5s so PM2/systemd/k8s
|
||||
// shutdown timeouts aren't held hostage.
|
||||
await Promise.race([
|
||||
this.#fastify.close(),
|
||||
new Promise<void>(resolve => setTimeout(resolve, 5_000)),
|
||||
]).catch(err => this.logger.error('fastify.close() failed', err as Error));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue