feat(bridge): connect when a pipe is already up after load fails
A failed load used to stay in the error state. If the pipe is already listening, connect instead, and keep retrying that case on later checks.
This commit is contained in:
@@ -309,7 +309,9 @@ export class HookManager {
|
||||
this.runAutoLoad(session, autoLoad);
|
||||
continue;
|
||||
}
|
||||
if ((session.status === 'connecting' || session.status === 'disconnected')
|
||||
if ((session.status === 'connecting'
|
||||
|| session.status === 'disconnected'
|
||||
|| session.status === 'error')
|
||||
&& this.pipeWatcher.isPipeLive(session.pid)) {
|
||||
session.onPipeUp();
|
||||
}
|
||||
|
||||
@@ -358,6 +358,15 @@ export class HookSession extends EventEmitter {
|
||||
this._error = errMsg(error);
|
||||
this.setStatus('error', this._error);
|
||||
this.log.error('load failed: PID=%d err=%s', this.pid, this._error);
|
||||
// The module can already be listening even when this call returns
|
||||
// failure: another load left it resident, or it came up after the
|
||||
// call returned. A live pipe still has the account state, so connect
|
||||
// instead of staying on the failed load.
|
||||
await this.pipeWatcher.tickNow?.();
|
||||
if (!this.disposed && this.pipeWatcher.isPipeLive(this.pid)) {
|
||||
this.log.info('PID=%d load failed but pipe is up; connecting', this.pid);
|
||||
await this.reconcilePipeUp();
|
||||
}
|
||||
}
|
||||
return this.toInfo();
|
||||
}
|
||||
|
||||
@@ -205,6 +205,35 @@ describe('HookSession — runtime TRACE', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('connects when load fails but the pipe is already up', async () => {
|
||||
let pipeLive = false;
|
||||
const clients: FakeClient[] = [];
|
||||
const session = new HookSession(7108, {
|
||||
injector: {
|
||||
inject: () => {
|
||||
pipeLive = true;
|
||||
throw new Error('component loading failed [COMPONENT_LOAD_FAILED]');
|
||||
},
|
||||
unload: () => undefined,
|
||||
},
|
||||
makeClient: () => {
|
||||
const client = new FakeClient();
|
||||
client.fireLogin('10001');
|
||||
clients.push(client);
|
||||
return client as unknown as QqHookClient;
|
||||
},
|
||||
pipeWatcher: {
|
||||
isPipeLive: () => pipeLive,
|
||||
tickNow: async () => undefined,
|
||||
},
|
||||
});
|
||||
const info = await session.load();
|
||||
expect(info.status).toBe('online');
|
||||
expect(info.uin).toBe('10001');
|
||||
expect(info.connected).toBe(true);
|
||||
expect(clients).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('records login, disconnect, and process-gone only when state changes', async () => {
|
||||
const entries: LogEntry[] = [];
|
||||
setLogLevel('trace');
|
||||
|
||||
Reference in New Issue
Block a user