mirror of
https://github.com/echore/vault-autopilot.git
synced 2026-07-22 08:34:00 +00:00
fix: survive server restart races and surface listen failures
restartServer now rebinds inside close()'s callback instead of the same tick, closing the close->listen race that produced EADDRINUSE. A failed listen (EADDRINUSE or otherwise) nulls the server reference and shows a Notice, so /ping and clips stop silently pretending the server is up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
596c8f87c9
commit
fbcbbb0701
3 changed files with 15 additions and 5 deletions
|
|
@ -46,6 +46,7 @@
|
|||
"notice.sopExportExists": "{path} already exists. The path now points to it.",
|
||||
"notice.savedTo": "Saved to {folder}\nWant a different location? Settings → Vault Autopilot → Storage locations",
|
||||
"notice.portInUse": "Vault Autopilot: port {port} is already in use. Quit the program using it, or set the same new port in both the plugin settings and the extension settings.",
|
||||
"notice.serverError": "Vault Autopilot: the local server on port {port} stopped. Toggle it off and on in settings to retry.",
|
||||
"notice.sectionExists": "\"{section}\" already exists — not overwritten. To redo it, delete that section first, then clip again.",
|
||||
"error.screenshotFolderNotConfigured": "Screenshots folder not configured: set it in Settings → Vault Autopilot → Storage locations → Screenshots folder.",
|
||||
"error.videoFolderNotConfigured": "Video notes folder or cover images folder not configured: set them in Settings → Vault Autopilot → Storage locations.",
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
"notice.sopExportExists": "{path} 已存在,路径已指向它。",
|
||||
"notice.savedTo": "已存到 {folder}\n想换位置?设置 → Vault Autopilot → 存储位置",
|
||||
"notice.portInUse": "Vault Autopilot:端口 {port} 被占用。请关闭占用它的程序;或在插件设置和扩展设置两处改成同一个新端口。",
|
||||
"notice.serverError": "Vault Autopilot:端口 {port} 上的本地服务已停止。请在设置里关闭再打开重试。",
|
||||
"notice.sectionExists": "「{section}」已存在,未覆盖。想重做请先删掉该小节再点。",
|
||||
"error.screenshotFolderNotConfigured": "截图文件夹未配置:请在 设置 → Vault Autopilot → 存储位置 → 截图文件夹 填写。",
|
||||
"error.videoFolderNotConfigured": "视频笔记文件夹或封面图片文件夹未配置:请在 设置 → Vault Autopilot → 存储位置 填写。",
|
||||
|
|
|
|||
18
src/main.ts
18
src/main.ts
|
|
@ -64,9 +64,13 @@ export default class VaultAutopilotPlugin extends Plugin {
|
|||
}
|
||||
|
||||
restartServer(): void {
|
||||
this.server?.close();
|
||||
const start = () => { if (this.settings.httpServer.enabled) this.startServer(); };
|
||||
const old = this.server;
|
||||
this.server = null;
|
||||
if (this.settings.httpServer.enabled) this.startServer();
|
||||
// Rebind only after the old socket has fully closed; starting on the same
|
||||
// tick races the close and hits EADDRINUSE on the same port.
|
||||
if (old) old.close(() => start());
|
||||
else start();
|
||||
}
|
||||
|
||||
private async ensureFolder(folderPath: string): Promise<void> {
|
||||
|
|
@ -179,9 +183,13 @@ export default class VaultAutopilotPlugin extends Plugin {
|
|||
this.manifest.version,
|
||||
);
|
||||
this.server.on('error', (err: NodeJS.ErrnoException) => {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
new Notice(t('notice.portInUse', { port }), 10000);
|
||||
}
|
||||
// A failed listen leaves a dead server; drop the reference so /ping and
|
||||
// clips report honestly and the next toggle/restart can rebind.
|
||||
this.server = null;
|
||||
new Notice(
|
||||
err.code === 'EADDRINUSE' ? t('notice.portInUse', { port }) : t('notice.serverError', { port }),
|
||||
10000,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue