{"record":{"id":"f6bc84c3ab6fa8a2","repo":"iflytek/astron-agent","slug":"errormessage-dynamic-error-message-or-fallback-failed-to","errorCode":null,"errorMessage":"errorMessage (dynamic; error.message or fallback 'Failed to upload image')","messagePattern":"errorMessage \\(dynamic; error\\.message or fallback 'Failed to upload image'\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"console/frontend/src/utils/utils.ts","lineNumber":454,"sourceCode":"          'Content-Type': file.type,\n        },\n      })\n      .put(url, file, {\n        headers: {\n          'Content-Type': file.type,\n        },\n      });\n    const fileUrl = url.split('?')[0];\n    return {\n      url: fileUrl,\n      objectKey: responseObjectKey,\n      fileName: file.name,\n      bucket,\n    };\n  } catch (error: unknown) {\n    const errorMessage =\n      error instanceof Error ? error.message : 'Failed to upload image';\n    throw new Error(errorMessage);\n  }\n}\n\n/**\n * 文本中间字符替换为星号（脱敏）\n * @param text 原始文本（必填）\n * @param options 配置项（可选）\n * - prefixLen 前面保留的字符数，默认 1\n * - suffixLen 后面保留的字符数，默认 1\n * - starLen 星号长度，默认 2（文本较长时自动调整，避免星号过多）\n * @returns 脱敏后的文本\n */\nexport const maskMiddleText = (\n  text: string,\n  options: { prefixLen?: number; suffixLen?: number; starLen?: number } = {}\n) => {\n  // 处理边界：文本为空、null/undefined 或非字符串，直接返回空\n  if (!text || typeof text !== 'string') return '';","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/frontend/src/utils/utils.ts#L436-L472","documentation":"uploadFile in utils.ts wraps its body in try/catch and rethrows a single Error whose message is error.message when the cause is an Error, otherwise the fallback 'Failed to upload image'. It preserves the underlying reason (network failure, presign failure, PUT rejection) but loses the original error type/stack.","triggerScenarios":"Any failure inside uploadFile: fetch of presigned upload URL fails, MinIO/S3 PUT returns non-2xx, network offline, invalid bucket or file object passed in, or a thrown non-Error value (string rejection).","commonSituations":"Expired/misconfigured object-storage credentials causing presign or PUT 403; oversized image hitting a proxy limit; CORS blocking the PUT to the storage endpoint; transient network loss during upload.","solutions":["Inspect error.message from the caught Error to identify whether presign or the PUT step failed","Check object-storage (MinIO/S3) credentials, bucket existence, and CORS config","Validate file size/type before calling uploadFile","Preserve the original error (cause) or rethrow it instead of flattening to a string for easier debugging"],"exampleFix":"// before\n} catch (error: unknown) {\n  const errorMessage = error instanceof Error ? error.message : 'Failed to upload image';\n  throw new Error(errorMessage);\n}\n// after\n} catch (error: unknown) {\n  if (error instanceof Error) throw error; // keep original stack\n  throw new Error('Failed to upload image: ' + String(error));\n}","handlingStrategy":"try-catch","validationCode":"if (!(file instanceof File) || file.size === 0 || file.size > MAX_UPLOAD_SIZE) {\n  throw new Error('Invalid or oversized file');\n}","typeGuard":"function isUploadable(f: unknown): f is File {\n  return f instanceof File && f.size > 0;\n}","tryCatchPattern":"try {\n  const res = await uploadFile(file, bucket);\n} catch (e) {\n  if (e instanceof Error) showToast(e.message);\n  else showToast('Failed to upload image');\n}","preventionTips":["Validate file size/type before upload","Check storage credentials and CORS config","Keep the original error's stack when rethrowing"],"tags":["upload","file","network","error-handling"],"backgroundTag":"http-request-failed","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}