{"record":{"id":"df75fa79ac45ccbc","repo":"yikart/AiToEarn","slug":"error-df75fa","errorCode":null,"errorMessage":"文件上传失败","messagePattern":"文件上传失败","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"project/aitoearn-electron/server/src/lib/oss/oss.service.ts","lineNumber":88,"sourceCode":"    const tempStr = mimetype.split('/');\n    const fileTypeStr = tempStr[tempStr.length - 1];\n\n    const stream = new Duplex();\n    stream.push(buffer);\n    stream.push(null);\n\n    try {\n      const upRes = await this.client.putStream(\n        `${path}/${newName}.${fileTypeStr}`,\n        stream,\n      );\n\n      const {\n        name,\n        res: { status },\n      } = upRes;\n\n      if (status !== HttpStatus.OK) throw new Error('文件上传失败');\n\n      return {\n        name,\n      };\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  /**\n   * 去除文件前置\n   * @param filePath\n   */\n  private noHostFilePath(filePath: string) {\n    const hostUrl = this.configService.get('OSS_CONFIG.HOST_URL');\n\n    const _hostUrl = hostUrl.replace('https', 'http');\n    if (filePath.indexOf(_hostUrl) === 0) {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/lib/oss/oss.service.ts#L70-L106","documentation":"upFileStream in oss.service uploads a file stream via Aliyun OSS and throws '文件上传失败' when the OSS client response status is not 200. The upload reached OSS but res.status signaled failure, so the file was not successfully stored.","triggerScenarios":"OSS putStream returns upRes.res.status !== HttpStatus.OK — invalid/expired STS credentials, bucket permission denied, network partial failure, wrong bucket/endpoint, or OSS returning 4xx/5xx.","commonSituations":"Expired AccessKeyId/Secret/STS token; bucket ACL changes; wrong region endpoint configured; oversized streams hitting timeouts; OSS throttling (503).","solutions":["Log the actual upRes.res.status and request-id to identify the OSS error.","Refresh OSS credentials (AK/SK or STS token) and verify env config.","Verify bucket name, endpoint region, and write permissions.","Retry transient failures (5xx/timeouts) with backoff; check network to OSS."],"exampleFix":"// before\nif (status !== HttpStatus.OK) throw new Error('文件上传失败');\n// after\nif (status !== HttpStatus.OK) {\n  console.error('OSS upload failed', { status, requestId: upRes.res.requestId, name });\n  throw new Error(`文件上传失败: OSS status ${status} (requestId=${upRes.res.requestId})`);\n}","handlingStrategy":"retry","validationCode":"function assertOssConfig(cfg) {\n  const required = ['region', 'accessKeyId', 'accessKeySecret', 'bucket'];\n  for (const k of required) {\n    if (!cfg[k]) throw new Error(`OSS 配置缺失: ${k}`);\n  }\n}\nassertOssConfig(ossConfig);","typeGuard":null,"tryCatchPattern":"let backoff = 1;\ntry {\n  await ossService.upFileStream(stream, key);\n} catch (e) {\n  if (e.message === '文件上传失败') {\n    await delay(backoff++ * 1000);\n    return retryUpload(stream, key); // 5xx/超时可重试\n  }\n  throw e;\n}","preventionTips":["Rotate/refresh OSS credentials before expiry; STS tokens are short-lived.","Log res.status and requestId from OSS responses instead of a bare message.","Confirm bucket write ACL and correct region endpoint.","Use retry with backoff for transient OSS 5xx; fail fast on 4xx (auth/permission)."],"tags":["oss","aliyun","upload","file-storage"],"backgroundTag":"oss-upload-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}