datawhalechina/hello-agents · error

生成旅行计划失败

Error message

生成旅行计划失败

What it means

The generic '生成旅行计划失败' (trip plan generation failed) is the last-resort message in generateTripPlan() (helloagents-trip-planner) when an axios POST to /api/trip/plan fails and neither error.response.data.detail nor error.message exists. The two richer variants (backend FastAPI `detail` or axios's own message) normally win; seeing the bare fallback means the failure carried no response body at all — typically a network-level or abort-level error.

Source

Thrown at code/chapter13/helloagents-trip-planner/frontend/src/services/api.ts:47

    console.log('收到响应:', response.status, response.config.url)
    return response
  },
  (error) => {
    console.error('响应错误:', error.response?.status, error.message)
    return Promise.reject(error)
  }
)

/**
 * 生成旅行计划
 */
export async function generateTripPlan(formData: TripFormData): Promise<TripPlanResponse> {
  try {
    const response = await apiClient.post<TripPlanResponse>('/api/trip/plan', formData)
    return response.data
  } catch (error: any) {
    console.error('生成旅行计划失败:', error)
    throw new Error(error.response?.data?.detail || error.message || '生成旅行计划失败')
  }
}

/**
 * 健康检查
 */
export async function healthCheck(): Promise<any> {
  try {
    const response = await apiClient.get('/health')
    return response.data
  } catch (error: any) {
    console.error('健康检查失败:', error)
    throw new Error(error.message || '健康检查失败')
  }
}

export default apiClient

View on GitHub (pinned to 606a07d341)

Solutions

  1. Check the console.error output right before the throw — it logs the full axios error with code (ECONNABORTED, ERR_NETWORK, ERR_BAD_REQUEST) that identifies the class of failure.
  2. If it's a timeout, raise axios `timeout` and any proxy timeouts; trip-plan LLM calls are slow.
  3. If it's ERR_NETWORK/none-response, verify the backend is up and the baseURL (apiClient) / dev proxy is configured for /api.
  4. If the backend returned 422/500, fix the TripFormData payload or backend issue per the logged `detail`.
  5. Type the catch as `unknown` and narrow with axios.isAxiosError to avoid the `error: any` smell.

Example fix

// before
} catch (error: any) {
  console.error('生成旅行计划失败:', error)
  throw new Error(error.response?.data?.detail || error.message || '生成旅行计划失败')
}

// after
import axios from 'axios'
// ...
} catch (error: unknown) {
  if (axios.isAxiosError(error)) {
    const detail = (error.response?.data as { detail?: string })?.detail
    throw new Error(detail || error.code || error.message || '生成旅行计划失败')
  }
  throw new Error('生成旅行计划失败')
}
Defensive patterns

Strategy: try-catch

Validate before calling

const required: (keyof TripFormData)[] = ['destination', 'days'];
const missing = required.filter((k) => !formData[k]);
if (missing.length) {
  throw new Error(`缺少必填字段: ${missing.join(', ')}`);
}

Type guard

import axios from 'axios';

function isAxiosErrorWithDetail(e: unknown): e is axios.AxiosError<{ detail: string }> {
  return axios.isAxiosError(e);
}

Try / catch

try {
  return await generateTripPlan(formData);
} catch (error: unknown) {
  if (axios.isAxiosError(error)) {
    if (error.code === 'ECONNABORTED') throw new Error('请求超时,请重试');
    const detail = (error.response?.data as { detail?: string })?.detail;
    throw new Error(detail || error.message);
  }
  throw error;
}

Prevention

When it happens

Trigger: axios POST /api/trip/plan rejects: backend FastAPI returns 422/500 with a `detail` field (shown instead), request times out (axios ECONNABORTED with a message), backend down so there is no response object (fallback fires), or the request was cancelled. Also triggers when the backend plan generation exceeds any configured proxy timeout.

Common situations: Long-running LLM plan generation hitting axios/proxy timeouts; backend not running; Vite dev proxy missing for /api; CORS block producing a network error with no response.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/3211946445dfeb6c. Report an issue: GitHub.