You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高声望用户评价问题时出现Cannot read properties of undefined错误排查

问题描述

开发了一个异步功能,用于实现高声望用户对普通用户的问题进行点赞或点踩:当问题获得-1票时,普通用户会扣除声望。但运行时出现错误:

ERROR [RpcExceptionsHandler] Cannot read properties of undefined (reading 'voto')

移除voto字段后,id、titulo等其他DTO属性也会报类似错误,疑似未获取到Postman的请求数据。相关代码如下:

问题服务(RabbitMQ)代码

async usuarioPrestigiadoAtualiza(idUsuario: string, idUsuarioPropio: string, idPergunta: string, dados: atualizaEspecificoDTO) {
    const usuario = await this.usuarioMetaRepository.findOne({where: {id: idUsuario}})
    if(usuario === null){
      throw new NotFoundException('Usuario Prestigiado nao existe')
    }
    const usuario2 = await this.usuarioMetaRepository.findOne({where: {id: idUsuarioPropio}})
    if(usuario2 === null){
      throw new NotFoundException('Usuario Propio nao existe')
    }
    const perguntaAchada = await this.perguntaRepository.findOne({where: {id: idPergunta}})
    if(perguntaAchada === null){
      throw new NotFoundException('Pergunta nao existe')
    }
    if(usuario.prestigio < 100){
      throw new UnauthorizedException(`Usuario: ${usuario.nome} nao possui prestigio suficiente!`)
    }
    if (dados.voto === -1) {
      usuario2.prestigio -= 5;
      usuario2.voteForce -= 2;
    } else if (dados.voto >= 1) {
      for (let i = 0; i < 100; i++) {
        if (usuario2.pergunta.voto + 1) {
          usuario2.prestigio += 4;
          usuario2.voteForce += 1;
        }
      }
    }
    if (usuario.voteForce > 30) {
      dados.voto *= 2;
    }
    if (usuario.voteForce > 60) {
      dados.voto *= 3;
    }
    if (usuario.voteForce >= 100) {
      dados.voto *= 4;
    }
    if(usuario2.prestigio >= 100){
      usuario2.prestigio === 100
    }
    perguntaAchada.id = dados.id
    perguntaAchada.titulo = dados.titulo
    perguntaAchada.voto = dados.voto
    perguntaAchada.pergunta = dados.pergunta
    const perguntaMudadaPorPrestigiado = await this.perguntaRepository.save(perguntaAchada)
    console.log(perguntaMudadaPorPrestigiado)
    return perguntaMudadaPorPrestigiado
  }

RabbitMQ控制器代码

@MessagePattern({ cmd: 'put-perguntaPrestigio'})
  async enviarPerguntaAvaliada(@Ctx() contexto: RmqContext, @Payload() payload: { idUsuario: string; idUsuarioPropio: string; idPergunta: string; dados: atualizaEspecificoDTO }) {
    const channel = contexto.getChannelRef()
    const message = contexto.getMessage()
    channel.ack(message)
    return this.perguntaService.usuarioPrestigiadoAtualiza(payload.idUsuario, payload.idUsuarioPropio, payload.idPergunta, payload.dados )

API网关控制器代码

@Put('usuarioM/:id1/:id2/:id3')
  async perguntaAtualizaPorPrestigiado(@Param('id1') idUsuario: string, @Param('id2') idUsuarioPropio: string, @Param('id3') idPergunta: string,  @Body() data: atualizaEspecificoDTO) {
    return this.authServico.send(
      {
        cmd: 'put-perguntaPrestigio'
      }, {idUsuario, idUsuarioPropio, idPergunta, data}
    )
  }
解决方案

1. 修复请求数据传递的字段名不匹配问题

这是导致dados为undefined的核心原因:

  • API网关控制器发送RabbitMQ消息时,传递的字段是data,但RabbitMQ控制器的payload期望接收的是dados字段,字段名不匹配导致payload.dados始终为undefined。
  • 调整API网关代码,将data改为dados字段:
@Put('usuarioM/:id1/:id2/:id3')
async perguntaAtualizaPorPrestigiado(@Param('id1') idUsuario: string, @Param('id2') idUsuarioPropio: string, @Param('id3') idPergunta: string,  @Body() data: atualizaEspecificoDTO) {
  return this.authServico.send(
    {
      cmd: 'put-perguntaPrestigio'
    }, {idUsuario, idUsuarioPropio, idPergunta, dados: data}
  )
}

2. 修复代码中的逻辑错误

  • 赋值操作错误:usuario2.prestigio === 100是比较运算符,无法实现声望上限限制,需改为赋值操作usuario2.prestigio = 100。
  • 无效循环逻辑:for (let i = 0; i < 100; i++)内的if (usuario2.pergunta.voto + 1)永远为true(除非voto=-1),会执行100次声望和voteForce累加,不符合业务预期,需根据实际需求调整判断条件,比如改为单次累加而非循环。
  • 不必要的ID更新:perguntaAchada.id = dados.id无意义,已通过idPergunta查到对应问题实体,无需修改ID,仅更新其他业务字段即可。

3. 验证DTO定义正确性

确保atualizaEspecificoDTO类正确定义了voto、titulo、pergunta等字段,并使用class-validator和class-transformer装饰器(如@IsNumber()、@IsString()),确保NestJS能正确解析Postman请求体数据。

内容的提问来源于stack exchange,提问作者J. Maciel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:35:46