axios+telemetry cleanup

This commit is contained in:
2026-04-02 15:19:11 +03:00
parent a3cbca1e11
commit 7e1eac8002
100 changed files with 3048 additions and 4491 deletions

View File

@@ -1,4 +1,3 @@
import axios, { type AxiosRequestConfig, type AxiosResponse } from 'axios'
import { randomUUID } from 'crypto'
import { getOauthConfig } from 'src/constants/oauth.js'
import { getOrganizationUUID } from 'src/services/oauth/client.js'
@@ -7,6 +6,7 @@ import { getClaudeAIOAuthTokens } from '../auth.js'
import { logForDebugging } from '../debug.js'
import { parseGitHubRepository } from '../detectRepository.js'
import { errorMessage, toError } from '../errors.js'
import { isHttpError, nativeRequest } from '../http.js'
import { lazySchema } from '../lazySchema.js'
import { logError } from '../log.js'
import { sleep } from '../sleep.js'
@@ -19,40 +19,40 @@ const MAX_TELEPORT_RETRIES = TELEPORT_RETRY_DELAYS.length
export const CCR_BYOC_BETA = 'ccr-byoc-2025-07-29'
/**
* Checks if an axios error is a transient network error that should be retried
* Checks if an error is a transient network error that should be retried
*/
export function isTransientNetworkError(error: unknown): boolean {
if (!axios.isAxiosError(error)) {
return false
if (isHttpError(error)) {
// Retry on server errors (5xx)
return !!error.status && error.status >= 500
}
// Retry on network errors (no response received)
if (!error.response) {
return true
// Treat generic Error as transient?
// Native fetch throws generic Error for network issues
if (error instanceof Error) {
const msg = error.message.toLowerCase()
return msg.includes('network') || msg.includes('timeout') || msg.includes('aborted')
}
// Retry on server errors (5xx)
if (error.response.status >= 500) {
return true
}
// Don't retry on client errors (4xx) - they're not transient
return false
}
/**
* Makes an axios GET request with automatic retry for transient network errors
* Makes a native GET request with automatic retry for transient network errors
* Uses exponential backoff: 2s, 4s, 8s, 16s (4 retries = 5 total attempts)
*/
export async function axiosGetWithRetry<T>(
export async function nativeGetWithRetry<T>(
url: string,
config?: AxiosRequestConfig,
): Promise<AxiosResponse<T>> {
options: { headers?: Record<string, string> } = {},
): Promise<{ data: T; status: number }> {
let lastError: unknown
for (let attempt = 0; attempt <= MAX_TELEPORT_RETRIES; attempt++) {
try {
return await axios.get<T>(url, config)
return await nativeRequest<T>(url, {
method: 'GET',
...options,
})
} catch (error) {
lastError = error
@@ -215,12 +215,12 @@ export async function fetchCodeSessionsFromSessionsAPI(): Promise<
'x-organization-uuid': orgUUID,
}
const response = await axiosGetWithRetry<ListSessionsResponse>(url, {
const response = await nativeGetWithRetry<ListSessionsResponse>(url, {
headers,
})
if (response.status !== 200) {
throw new Error(`Failed to fetch code sessions: ${response.statusText}`)
throw new Error(`Failed to fetch code sessions: ${response.status}`)
}
// Transform SessionResource[] to CodeSession[] format
@@ -298,10 +298,10 @@ export async function fetchSession(
'x-organization-uuid': orgUUID,
}
const response = await axios.get<SessionResource>(url, {
const response = await nativeRequest<SessionResource>(url, {
method: 'GET',
headers,
timeout: 15000,
validateStatus: status => status < 500,
})
if (response.status !== 200) {
@@ -319,7 +319,7 @@ export async function fetchSession(
throw new Error(
apiMessage ||
`Failed to fetch session: ${response.status} ${response.statusText}`,
`Failed to fetch session: ${response.status}`,
)
}
@@ -393,9 +393,10 @@ export async function sendEventToRemoteSession(
)
// The endpoint may block until the CCR worker is ready. Observed ~2.6s
// in normal cases; allow a generous margin for cold-start containers.
const response = await axios.post(url, requestBody, {
const response = await nativeRequest<any>(url, {
method: 'POST',
body: requestBody,
headers,
validateStatus: status => status < 500,
timeout: 30000,
})
@@ -439,14 +440,11 @@ export async function updateSessionTitle(
logForDebugging(
`[updateSessionTitle] Updating title for session ${sessionId}: "${title}"`,
)
const response = await axios.patch(
url,
{ title },
{
headers,
validateStatus: status => status < 500,
},
)
const response = await nativeRequest<any>(url, {
method: 'PATCH',
body: { title },
headers,
})
if (response.status === 200) {
logForDebugging(

View File

@@ -1,8 +1,8 @@
import axios from 'axios'
import { getOauthConfig } from 'src/constants/oauth.js'
import { getOrganizationUUID } from 'src/services/oauth/client.js'
import { getClaudeAIOAuthTokens } from '../auth.js'
import { toError } from '../errors.js'
import { nativeRequest } from '../http.js'
import { logError } from '../log.js'
import { getOAuthHeaders } from './api.js'
@@ -50,15 +50,14 @@ export async function fetchEnvironments(): Promise<EnvironmentResource[]> {
'x-organization-uuid': orgUUID,
}
const response = await axios.get<EnvironmentListResponse>(url, {
const response = await nativeRequest<EnvironmentListResponse>(url, {
method: 'GET',
headers,
timeout: 15000,
})
if (response.status !== 200) {
throw new Error(
`Failed to fetch environments: ${response.status} ${response.statusText}`,
)
throw new Error(`Failed to fetch environments: ${response.status}`)
}
return response.data.environments
@@ -86,9 +85,9 @@ export async function createDefaultCloudEnvironment(
}
const url = `${getOauthConfig().BASE_API_URL}/v1/environment_providers/cloud/create`
const response = await axios.post<EnvironmentResource>(
url,
{
const response = await nativeRequest<EnvironmentResource>(url, {
method: 'POST',
body: {
name,
kind: 'anthropic_cloud',
description: '',
@@ -107,14 +106,12 @@ export async function createDefaultCloudEnvironment(
},
},
},
{
headers: {
...getOAuthHeaders(accessToken),
'anthropic-beta': 'ccr-byoc-2025-07-29',
'x-organization-uuid': orgUUID,
},
timeout: 15000,
headers: {
...getOAuthHeaders(accessToken),
'anthropic-beta': 'ccr-byoc-2025-07-29',
'x-organization-uuid': orgUUID,
},
)
timeout: 15000,
})
return response.data
}