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

Mikro ORM验证错误未被捕获,Socket请求挂起如何修复?

修复方案

核心问题分析

  1. 异步操作未加await:原代码中this.em.persistAndFlush(created)没有添加await,导致该异步操作的错误无法被当前try/catch捕获,Promise会在try块外部拒绝,这是错误未被捕获的核心原因。
  2. 未处理ValidationError:当前catch块仅处理了NotFoundError,未覆盖ORM验证抛出的ValidationError。
  3. Socket异常传递错误:直接抛出HTTP风格异常(如NotFoundException)无法在Socket上下文正确传递,导致请求挂起。

具体修复代码

@SubscribeMessage('sendMessage')
async handleSendMessage(
  client: Socket,
  payload: CreateMessageInput,
): Promise<void> {
  // 提前拦截必填参数缺失的情况
  if (!payload.userId) {
    client.emit('sendMessageError', 'User ID is required.');
    return;
  }

  try {
    const created = this.em.create(Chat, {
      text: payload.text,
      user: payload.userId,
    });
    // 给异步操作添加await,确保错误能被try/catch捕获
    await this.em.persistAndFlush(created);

    const { userName } = await this.em.findOneOrFail(User, {
      id: payload.userId,
    });

    this.server.emit('receiveMessage', {
      text: payload.text,
      user: { userName, id: payload.userId },
    });
  } catch (e) {
    // 根据错误类型返回对应提示,通过自定义错误事件传递给客户端
    if (e.name === 'NotFoundError') {
      client.emit('sendMessageError', 'User not found.');
    } else if (e.name === 'ValidationError') {
      client.emit('sendMessageError', 'Invalid message data: user is required.');
    } else {
      client.emit('sendMessageError', 'Something went wrong');
    }
  }
}

关键优化点

  1. 添加await捕获异步错误:给persistAndFlush添加await,确保ORM操作的错误能进入try/catch流程。
  2. 提前参数验证:在ORM操作前先检查payload.userId是否存在,避免触发ORM的验证逻辑,减少不必要的数据库交互。
  3. Socket错误事件传递:通过自定义错误事件(如sendMessageError)将错误信息发送给发起请求的客户端,替代HTTP风格异常,避免请求挂起。
  4. 覆盖ValidationError处理:在catch块中识别ValidationError类型,返回明确的错误提示。

内容的提问来源于stack exchange,提问作者Bowis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:27:26