【问题标题】:NestJs Microservice RPC Exception HandlingNestJs微服务RPC异常处理
【发布时间】:2022-11-30 13:39:32
【问题描述】:

我对 NestJS 中跨微服务的正确异常处理有疑问。当前设置如下所示。客户端请求 ==(REST)==> API 网关 ==(RabbitMQ / RPC)==> Service-A

在 Service-A 中发生异常,我将其作为 RPC 异常抛出并希望在 API 网关中转换为 HTTPException。

我的 API 网关的结构如下所示 => 控制器 => 服务 => RabbitMQ RPC 请求

我的服务 A 看起来像这样: => Controller => Service => CQRS => CommandHandler => GenericRepo 等。

从那以后我发现最好在控制器中处理异常。因此,我的 API 控制器和 API 服务如下所示。

@ApiTags('User')
@Controller('user')
export class UserController {
  private readonly _logger = new Logger(UserController.name);

  constructor(
    @Inject(IRESETSERVICE) private readonly _userService: UserService
    ) {}

  @ApiOperation({ summary: 'Create a new user' })
  @ApiCreatedResponse({ description: 'The user has been successfully created.' })
  @ApiUnprocessableEntityResponse({ description: 'The user could not be created.' })
  @ApiForbiddenResponse({ description: 'Forbidden.' })
  @ApiUnauthorizedResponse({ description: 'Unauthorized.' })
  @ApiInternalServerErrorResponse({ description: 'Internal server error.' })
  @Post()
  async create(@Body() createUserDto: CreateUserDto) {
    try {
      return  this._userService.create(createUserDto);
    }
    catch (error) {
        this._logger.error(error.message);
        return error;
    }
  }
}
@Injectable()
export class UserService implements IRestService {
  private readonly _logger = new Logger(UserService.name)

  constructor(
    private readonly _amqpService: AmqpService    
  ) {};

  async create(createUserDto: CreateUserDto): Promise<CreateUserResponseDto> {
    return this._amqpService.request(AmqpExchange.ACCOUNT_SERVICE, AmqpRoutingKey.USER + AmqpRoutingKeyOperation.CREATE, { dto: createUserDto });
  }
}

服务中的控制器包括。服务本身看起来像这样:

@Controller()
export class UserController {
  private readonly _logger = new Logger(UserService.name)
  
  constructor(
    @Inject(IAMQPSERVICE) private readonly _usersService: UserService
    ) {}

  @RabbitRPC({
    exchange: AmqpExchange.ACCOUNT_SERVICE,
    routingKey: AmqpRoutingKey.USER + AmqpRoutingKeyOperation.CREATE,
    queue: AmqpRoutingKey.USER + AmqpRoutingKeyOperation.CREATE,
  })
  async create(@RabbitPayload() payload) {
    return this._usersService.create(payload.request.dto);
  }
}
@Injectable()
export class UserService implements IAmqpService {
  private readonly _logger = new Logger(UserService.name)

  constructor(
    private readonly _queryBus: QueryBus,
    private readonly _commandBus: CommandBus,
  ) {}

  async create(createUserDto: CreateUserDto) {
    return this._commandBus.execute(new CreateUserCommand(createUserDto));
  }
}
@CommandHandler(CreateUserCommand)
export class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
  
  constructor(
    private _userUseCases: UserUseCases,
    private _userFactoryService: UserFactoryService
  ) {}

  async execute(command: CreateUserCommand) {
    console.log('Async CreateUserCommand...');

    const createUserResponse = new CreateUserResponseDto();
    try {
      const user = this._userFactoryService.createNewUser(command.createUserDto);
      const createdUser = await this._userUseCases.createUser(user);

      createUserResponse.success = true;
      createUserResponse.createdUser = createdUser;
    } catch (error) {
      // report and log error
      createUserResponse.success = false;
      return new MyRpcException(error,500);
    }

    return createUserResponse;

  }
}

`

CommandHandler (MyRpcException) 中抛出的异常我准备好作为响应,但邮递员显示状态 201(已创建)尽管 500。我的 MyRpcException 解决方案来自:How to handle RpcException in NestJS 但没有工作(最后评论)

我测试了自定义 ExceptionFilter

【问题讨论】:

    标签: typescript exception nestjs nestjs-exception-filters


    【解决方案1】:

    您在这里返回异常而不是抛出它:

    return new MyRpcException(error,500);
    

    尝试用 throw 替换 return。

    【讨论】:

      猜你喜欢
      • 2020-10-20
      • 1970-01-01
      • 2022-06-15
      • 2020-06-09
      • 2018-03-16
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      相关资源
      最近更新 更多