{"record":{"id":"ff01d0363a50ca18","repo":"yikart/AiToEarn","slug":"fail","errorCode":"fail","errorMessage":"fail","messagePattern":"fail","errorType":"error_code","errorClass":"AppHttpException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-electron/server/src/modules/task/adminTask.controller.ts","lineNumber":130,"sourceCode":"    @Query() query: PagerDto,\n  ) {\n    return this.adminTaskService.findTaskMaterialList(taskId, query);\n  }\n\n  // 添加任务素材列表\n  @Post('material')\n  async addTaskMaterial(@Body() body: ActionTaskMaterialDto) {\n    return this.adminTaskService.createTaskMaterial(body);\n  }\n\n  // 更新任务素材\n  @Put('material/:id')\n  async upTaskMaterial(\n    @Param('id') id: string,\n    @Body() body: ActionTaskMaterialDto,\n  ) {\n    const info = await this.adminTaskService.getTaskMaterialById(id);\n    if (!info) throw new AppHttpException(ErrHttpBack.fail);\n\n    return this.adminTaskService.upTaskMaterial(id, body);\n  }\n\n  // 删除任务素材\n  @Delete('material/:id')\n  async deleteTaskMaterial(@Param('id') id: string) {\n    return this.adminTaskService.deleteTaskMaterial(id);\n  }\n}\n","sourceCodeStart":112,"sourceCodeEnd":141,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/modules/task/adminTask.controller.ts#L112-L141","documentation":"Generic failure AppHttpException thrown from the admin task-material update endpoint. It means the material id given in PUT /material/:id does not correspond to any stored task material record. The controller checks getTaskMaterialById first and throws ErrHttpBack.fail before any update happens.","triggerScenarios":"PUT material/:id (admin task routes) with an id that is not a valid existing task-material id: already-deleted material, malformed/typo id, or an id belonging to another collection.","commonSituations":"Stale client caches referencing deleted materials, copy-pasting an id of the wrong entity type (task id vs material id), or testing against a different database than the one the material was created in.","solutions":["Verify the material id exists via the task material list/get endpoint before calling PUT material/:id.","Check you are not passing a task id instead of a task-material id.","Confirm the admin client is pointed at the same environment/database where the material was created.","If the generic 'fail' code is unhelpful, replace it with a more specific ErrHttpBack entry for not-found materials."],"exampleFix":"// before\nconst info = await this.adminTaskService.getTaskMaterialById(id);\nif (!info) throw new AppHttpException(ErrHttpBack.fail);\n// after\nconst info = await this.adminTaskService.getTaskMaterialById(id);\nif (!info)\n  throw new NotFoundException(`Task material ${id} not found`);","handlingStrategy":"validation","validationCode":"const info = await api.getTaskMaterialById(id);\nif (!info) throw new Error(`Skip update: material ${id} not found`);\nawait api.put(`/material/${id}`, body);","typeGuard":"function isMaterial(m: unknown): m is { id: string } {\n  return !!m && typeof m === 'object' && typeof (m as any).id === 'string';\n}","tryCatchPattern":"try {\n  await api.put(`/material/${id}`, body);\n} catch (e) {\n  if (e.response?.data?.code === 'fail') {\n    console.warn(`Material ${id} not found; refreshing list`);\n    await refreshMaterialList();\n  } else throw e;\n}","preventionTips":["Always resolve material ids from a fresh list call, never from cached form state.","Keep task ids and material ids in distinct, labeled fields to avoid mixups.","Wrap admin mutations with a pre-check read of the entity."],"tags":["rest","not-found","admin-api","mongodb"],"backgroundTag":"resource-not-found","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}