yikart/AiToEarn · error · NotFoundException

任务状态不正确

Error message

任务状态不正确

What it means

HTTP 404 NotFoundException '任务状态不正确' thrown when the userTask exists and is owned by the caller, but its status is not UserTaskStatus.APPROVED (task.controller.ts:145). Withdrawals are only allowed on approved tasks, so status gating reuses 404 here.

Source

Thrown at project/aitoearn-electron/server/src/modules/task/task.controller.ts:145

    }

    return res;
  }

  // 任务提现(创建提现数据)
  @ApiOperation({ summary: '用户任务提现' })
  @ApiResult({ type: Boolean })
  @Post('withdraw/:id')
  async withdrawCashUserTask(
    @GetToken() token: TokenInfo,
    @Param('id') id: string,
    @Body() data: { accountId: string },
  ) {
    const userTask = await this.userTaskService.getUserTaskInfoById(id);
    if (!userTask || userTask.userId.toString() !== token.id)
      throw new NotFoundException('任务不存在');
    if (userTask.status !== UserTaskStatus.APPROVED)
      throw new NotFoundException('任务状态不正确');
    const account = await this.financeService.getUserWalletAccountById(
      data.accountId,
    );
    if (!account) throw new NotFoundException('钱包账户不存在');

    return await this.financeService.createUserWalletRecord(token.id, account, {
      dataId: userTask.id,
      type: UserWalletRecordType.WITHDRAW,
      balance: userTask.reward, // 将 number 转换为 Decimal128
      des: '任务提现',
      status: UserWalletRecordStatus.WAIT,
    });
  }

  @ApiOperation({ summary: '统计合计进行中的任务的金额总数' })
  @Get('reward/amount')
  @ApiResult({ type: Number })
  async getTotalAmountOfDoingTasks(@GetToken() token: TokenInfo) {

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Only withdraw after the task status is APPROVED — poll the userTask status first
  2. Handle the approval notification/event before triggering withdrawal
  3. If the task should be approved, contact the task admin/auditor rather than retrying
  4. Surface the current status to the user in the UI instead of blindly calling withdraw

Example fix

// before
await api.withdrawCash(userTask.id, { accountId }) // status may be PENDING
// after
const ut = await api.getUserTaskInfo(userTask.id)
if (ut.status === 'APPROVED') await api.withdrawCash(userTask.id, { accountId })
Defensive patterns

Strategy: validation

Validate before calling

const ut = await api.getUserTaskInfo(userTaskId)
if (ut.status !== 'APPROVED') {
  throw new Error(`Withdrawal requires APPROVED status, current: ${ut.status}`)
}

Type guard

function isApproved(ut: UserTask): boolean {
  return ut.status === 'APPROVED'
}

Try / catch

try {
  await api.withdrawCash(userTaskId, { accountId })
} catch (e) {
  if (e?.status === 404 && e?.message === '任务状态不正确') {
    // poll status until APPROVED or show waiting-for-approval UI
  } else throw e
}

Prevention

When it happens

Trigger: Calling the withdraw-cash endpoint while the userTask is PENDING, DODING, or REJECTED — i.e. before the task submission has been approved by the auditor.

Common situations: User tries to withdraw right after submitting, before admin approval; automated client retries withdrawal without re-checking status; task was approved then reset to a different status.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/c634b03cec0bafe6. Report an issue: GitHub.