feat(telegram): harden channel reliability with retries and error diagnostics
This commit is contained in:
@@ -116,6 +116,29 @@ describe('discoverServices', () => {
|
||||
expect(services.find(s => s.name === 'telegram')?.status).toBe('connected');
|
||||
});
|
||||
|
||||
it('surfaces adapter error details when channel is in error state', () => {
|
||||
const cfg = makeBaseConfig();
|
||||
withMutableConfig(cfg).telegram = { bot_token: 'x', allowed_chat_ids: [123], require_mention: false };
|
||||
|
||||
const reg = new ChannelRegistry();
|
||||
reg.register({
|
||||
name: 'telegram',
|
||||
status: 'error',
|
||||
lastError: 'Telegram polling error: 429 Too Many Requests',
|
||||
lastErrorAt: 1708080000000,
|
||||
connect: async () => {},
|
||||
disconnect: async () => {},
|
||||
send: async () => {},
|
||||
onMessage: () => {},
|
||||
});
|
||||
|
||||
const services = discoverServices(cfg, reg);
|
||||
const telegram = services.find(s => s.name === 'telegram');
|
||||
expect(telegram?.status).toBe('error');
|
||||
expect(telegram?.error).toContain('429');
|
||||
expect(telegram?.metadata).toMatchObject({ lastErrorAt: 1708080000000 });
|
||||
});
|
||||
|
||||
it('marks enabled automation subsystems as configured and carries item counts', () => {
|
||||
const cfg = makeBaseConfig();
|
||||
cfg.automation.cron = [
|
||||
|
||||
@@ -73,7 +73,14 @@ export function discoverServices(
|
||||
}
|
||||
|
||||
if (registered) {
|
||||
services.push({ name, type: 'channel', status: registered.status as ServiceStatus, description });
|
||||
services.push({
|
||||
name,
|
||||
type: 'channel',
|
||||
status: registered.status as ServiceStatus,
|
||||
description,
|
||||
...(registered.lastError ? { error: registered.lastError } : {}),
|
||||
...(registered.lastErrorAt ? { metadata: { lastErrorAt: registered.lastErrorAt } } : {}),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ export interface SystemHandlerDeps {
|
||||
getConnectionCount: () => number;
|
||||
/** Optional callback to trigger a graceful restart. If not provided, system.restart returns an error. */
|
||||
restart?: () => Promise<void>;
|
||||
getChannels?: () => Array<{ name: string; status: string }>;
|
||||
getChannels?: () => Array<{ name: string; status: string; error?: string; lastErrorAt?: number }>;
|
||||
getUsage?: () => { totalSessions: number; activeConnections: number };
|
||||
/** Optional callback to retrieve per-session token usage data. */
|
||||
getTokenUsage?: () => TokenUsageEntry[];
|
||||
|
||||
@@ -213,7 +213,12 @@ export class GatewayServer {
|
||||
getSessionAnalytics: ({ days, topLimit } = {}) => this.config.sessionManager.getSessionAnalytics({ days, topLimit }),
|
||||
restart: this.config.restart,
|
||||
getChannels: channelRegistry
|
||||
? () => channelRegistry.list().map(a => ({ name: a.name, status: a.status }))
|
||||
? () => channelRegistry.list().map(a => ({
|
||||
name: a.name,
|
||||
status: a.status,
|
||||
...(a.lastError ? { error: a.lastError } : {}),
|
||||
...(a.lastErrorAt ? { lastErrorAt: a.lastErrorAt } : {}),
|
||||
}))
|
||||
: undefined,
|
||||
getServices: runtimeConfig && channelRegistry
|
||||
? () => discoverServices(runtimeConfig, channelRegistry)
|
||||
|
||||
@@ -818,6 +818,7 @@ function updateServices(servicesData) {
|
||||
</div>
|
||||
<span class="text-xs uppercase ${statusColor}">${escapeHtml(svc.status)}</span>
|
||||
<span class="text-xs text-zinc-500">${escapeHtml(svc.description)}</span>
|
||||
${svc.error ? `<span class="text-xs text-red-400">Error: ${escapeHtml(String(svc.error))}</span>` : ''}
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user