diff --git a/backend/src/common/filters/all-exceptions.filter.ts b/backend/src/common/filters/all-exceptions.filter.ts index afe1e47..0f660dd 100644 --- a/backend/src/common/filters/all-exceptions.filter.ts +++ b/backend/src/common/filters/all-exceptions.filter.ts @@ -16,7 +16,7 @@ export class AllExceptionsFilter implements ExceptionFilter { const message = exception instanceof HttpException ? exception.getResponse() - : '服务器内部错误'; + : (exception as Error)?.message || '服务器内部错误'; const errorResponse = { code: status, diff --git a/backend/src/modules/interview/interview.service.ts b/backend/src/modules/interview/interview.service.ts index 57bc085..2211cf6 100644 --- a/backend/src/modules/interview/interview.service.ts +++ b/backend/src/modules/interview/interview.service.ts @@ -1,4 +1,4 @@ -import { Injectable, HttpException, HttpStatus } from '@nestjs/common' +import { Injectable, HttpException, HttpStatus, Logger } from '@nestjs/common' import { InjectModel } from '@nestjs/mongoose' import { Model } from 'mongoose' import { Interview, InterviewDocument } from './interview.schema' @@ -11,6 +11,8 @@ import { analyzeSpeech } from '../../common/utils/filler-words' @Injectable() export class InterviewService { + private readonly logger = new Logger(InterviewService.name) + constructor( @InjectModel(Interview.name) private interviewModel: Model, @InjectModel(Progress.name) private progressModel: Model, @@ -25,11 +27,17 @@ export class InterviewService { const cost = await this.quotaService.checkInterview(userId) // Step 2: AI 生成第一个问题 - const firstQuestion = await this.aiService.call({ - systemPrompt: `你是一位专业的${position}面试官。请针对校招该岗位提出第一个面试问题,要求具体且有针对性。直接输出问题,不要多余内容。`, - userMessage: `请为${position}岗位的校招候选人提出第一个面试问题。`, - temperature: 0.8, - }) + let firstQuestion: string + try { + firstQuestion = await this.aiService.call({ + systemPrompt: `你是一位专业的${position}面试官。请针对校招该岗位提出第一个面试问题,要求具体且有针对性。直接输出问题,不要多余内容。`, + userMessage: `请为${position}岗位的校招候选人提出第一个面试问题。`, + temperature: 0.8, + }) + } catch (e) { + this.logger.error(`AI call failed for interview create: ${(e as Error).message}`) + throw new HttpException('AI 服务暂时不可用,请稍后重试', HttpStatus.SERVICE_UNAVAILABLE) + } // Step 3: AI 调用成功后,扣除引力值并创建面试记录 await this.quotaService.deductInterview(userId, cost) diff --git a/zhiyin-app/src/pages/interview/interview.vue b/zhiyin-app/src/pages/interview/interview.vue index 1dd218e..41350dd 100644 --- a/zhiyin-app/src/pages/interview/interview.vue +++ b/zhiyin-app/src/pages/interview/interview.vue @@ -242,7 +242,8 @@ const startInterview = async () => { } else if (checkAuth(res)) { return // token 过期,已清除并跳转登录 } else { - const msg = res.data?.message || '创建面试失败' + const errMsg = typeof res.data === 'string' ? res.data : (res.data?.message || '') + const msg = errMsg || `创建面试失败(${res.statusCode})` messages.value.push({ role: 'ai', content: msg }) } } catch {