fix: add retry logic to daemon machine registration for transient connection errors

Add exponential backoff retry mechanism to handle ECONNREFUSED errors when the
server isn't ready yet during daemon startup. This includes:

- New errorUtils module with error classification helpers
- withRetry function in time.ts supporting configurable exponential backoff
- Machine registration retry with sensible defaults (60 attempts, 1-30s delays)
- Error refactoring to consolidate extractErrorInfo utility

close #35
This commit is contained in:
weishu
2026-01-08 11:37:29 +08:00
parent c0446766a5
commit 1665c63d95
4 changed files with 170 additions and 42 deletions
+1 -35
View File
@@ -10,43 +10,9 @@ import { initializeToken } from '@/ui/tokenInit'
import { spawnHappyCLI } from '@/utils/spawnHappyCLI'
import { maybeAutoStartServer } from '@/utils/autoStartServer'
import { withBunRuntimeEnv } from '@/utils/bunRuntime'
import { extractErrorInfo } from '@/utils/errorUtils'
import type { CommandDefinition } from './types'
function extractErrorInfo(error: unknown): {
message: string
messageLower: string
axiosCode?: string
httpStatus?: number
responseErrorText: string
} {
const message = error instanceof Error ? error.message : 'Unknown error'
const messageLower = message.toLowerCase()
if (typeof error !== 'object' || error === null) {
return { message, messageLower, responseErrorText: '' }
}
const record = error as Record<string, unknown>
const axiosCode = typeof record.code === 'string' ? record.code : undefined
const response = typeof record.response === 'object' && record.response !== null
? (record.response as Record<string, unknown>)
: undefined
const httpStatus = typeof response?.status === 'number' ? response.status : undefined
const responseData = response?.data
const responseError = typeof responseData === 'object' && responseData !== null
? (responseData as Record<string, unknown>).error
: undefined
const responseErrorText = typeof responseError === 'string' ? responseError : ''
return {
message,
messageLower,
axiosCode,
httpStatus,
responseErrorText
}
}
export const claudeCommand: CommandDefinition = {
name: 'default',
requiresRuntimeAssets: true,