nest js 中出现超时异常,无法停止方法执行

问题描述 投票:0回答:1

我有一个带有一个端点的 Nest api。如果应用程序在 60 秒内没有响应,我想抛出 RequestTimeoutException(),并停止执行所调用的方法而不停止程序本身。我可以向客户端抛出异常,但即使已经抛出异常,应用程序仍会继续执行。

我尝试过以下方法:

  1. 使用拦截器:这允许向客户端抛出异常,但不会停止所调用方法的执行。
@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(60000),
      catchError((err) => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  }
}
@Controller('chatbot')
@UseInterceptors(TimeoutInterceptor)
export class ChatbotController {
  private readonly chatbotService = new ChatbotService();

  @Post('query')
  async postQuery(@Body() body: QueryModel) {
    if (
      !body.chatInfo ||
      !body.chatInfo.chatId ||
      !body.chatInfo.userId ||
      !body.question
    )
      throw new BadRequestException();

    const response = await this.chatbotService.generateResponse(body);

    return response;
  }
}
  1. 使用超时:这会停止程序的执行。
@Post('query')
  async postQuery(@Body() body: QueryModel) {
    let timeoutHandler: NodeJS.Timeout
    try {
      timeoutHandler = setTimeout(() => {
        throw new RequestTimeoutException()
      }, 60000)

      if (
        !body.chatInfo ||
        !body.chatInfo.chatId ||
        !body.chatInfo.userId ||
        !body.question
      )
        throw new BadRequestException();
  
      const response = await this.chatbotService.generateResponse(body);
      
      clearTimeout(timeoutHandler)
      return response;
    } catch (error) {
      clearTimeout(timeoutHandler)
      throw error;  // or return error;
    }
  }
nest
1个回答
0
投票

您应该定义一个AbortController并将其传递给generateResponse方法,并在60000秒后中止控制器,它应该是这样的:

@Controller('chatbot')
@UseInterceptors(TimeoutInterceptor)
export class ChatbotController {
  private readonly chatbotService = new ChatbotService();

  @Post('query')
  async postQuery(@Body() body: QueryModel) {
    if (!body.chatInfo !body.chatInfo.chatId !body.chatInfo.userId !body.question) {
      throw new BadRequestException();
    }

    const controller = new AbortController(); 
    const signal = controller.signal;  

    let timeoutHandler: NodeJS.Timeout = setTimeout(() => {
      controller.abort();  
    }, 60000);

    try {
      const response = await this.chatbotService.generateResponse(body, signal);
      clearTimeout(timeoutHandler);
      return response;
    } catch (error) {
      clearTimeout(timeoutHandler);
      if (signal.aborted) {
        throw new RequestTimeoutException();
      }
      throw error;
    }
  }
}

和服务:

@Injectable()
export class ChatbotService {
  async generateResponse(body: QueryModel, signal?: AbortSignal): Promise<any> {
    if (signal?.aborted) {
      throw new RequestTimeoutException();
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.