{"record":{"id":"ce203ad39f3f4091","repo":"elunez/eladmin","slug":"error-ce203a","errorCode":null,"errorMessage":"文件不存在或已被删除","messagePattern":"文件不存在或已被删除","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"eladmin-tools/src/main/java/me/zhengjie/service/impl/S3StorageServiceImpl.java","lineNumber":179,"sourceCode":"            map.put(\"文件名称\", s3Storage.getFileName());\n            map.put(\"真实存储的名称\", s3Storage.getFileRealName());\n            map.put(\"文件大小\", s3Storage.getFileSize());\n            map.put(\"文件MIME 类型\", s3Storage.getFileMimeType());\n            map.put(\"文件类型\", s3Storage.getFileType());\n            map.put(\"文件路径\", s3Storage.getFilePath());\n            map.put(\"创建者\", s3Storage.getCreateBy());\n            map.put(\"更新者\", s3Storage.getUpdateBy());\n            map.put(\"创建日期\", s3Storage.getCreateTime());\n            map.put(\"更新时间\", s3Storage.getUpdateTime());\n            list.add(map);\n        }\n        FileUtil.downloadExcel(list, response);\n    }\n\n    public Map<String, String> privateDownload(Long id) {\n        S3Storage storage = s3StorageRepository.findById(id).orElse(null);\n        if (storage == null) {\n            throw new BadRequestException(\"文件不存在或已被删除\");\n        }\n        // 创建 GetObjectRequest，指定存储桶和文件键\n        GetObjectRequest getObjectRequest = GetObjectRequest.builder()\n                .bucket(amzS3Config.getDefaultBucket())\n                .key(storage.getFilePath())\n                .build();\n        String base64Data;\n        // 使用 try-with-resources 确保流能被自动关闭\n        // s3Client.getObject() 返回一个 ResponseInputStream，它是一个包含S3对象数据的输入流\n        try (ResponseInputStream<GetObjectResponse> s3InputStream = s3Client.getObject(getObjectRequest)) {\n            // 使用 IOUtils.toByteArray 将输入流直接转换为字节数组\n            byte[] fileBytes = IOUtils.toByteArray(s3InputStream);\n            // 使用 Java 内置的 Base64 编码器将字节数组转换为 Base64 字符串\n            base64Data = Base64.getEncoder().encodeToString(fileBytes);\n        } catch (S3Exception e) {\n            // 处理 AWS 特定的异常\n            throw new BadRequestException(\"从 S3 下载文件时出错: \" + e.awsErrorDetails().errorMessage());\n        } catch (IOException e) {","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-tools/src/main/java/me/zhengjie/service/impl/S3StorageServiceImpl.java#L161-L197","documentation":"Thrown by S3StorageServiceImpl.privateDownload when s3StorageRepository.findById(id) returns empty — the requested file record is not in the database (never existed or already deleted). It fails before any S3 call, distinguishing a metadata miss from an S3-side error (errors 94/95).","triggerScenarios":"GET the private-download endpoint with an id that isn't in s3_storage: stale UI list after another admin deleted files, hand-edited id, or a record removed by deleteAll while a user still had the row open.","commonSituations":"Frontend caching an old file list; concurrent deletion; bookmarked/download links persisted after cleanup jobs; id confusion between local storage and S3 storage tables.","solutions":["Refresh the file list from the server and use a current id.","If the record should exist, check the s3_storage table (was it deleted by a batch operation?).","Handle the 400 gracefully in the UI with a 'file no longer available' state.","For long-lived links, persist download requests server-side rather than raw ids."],"exampleFix":"// before\nS3Storage storage = s3StorageRepository.findById(id).orElse(null);\nif (storage == null) {\n    throw new BadRequestException(\"文件不存在或已被删除\");\n}\n\n// after: use orElseThrow for the same behavior, less ceremony\nS3Storage storage = s3StorageRepository.findById(id)\n        .orElseThrow(() -> new BadRequestException(\"文件不存在或已被删除\"));","handlingStrategy":"validation","validationCode":"// caller-side existence check before requesting download\nboolean exists = s3StorageRepository.existsById(id);\nif (!exists) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(\"文件不存在或已被删除\"); }","typeGuard":null,"tryCatchPattern":"try { s3StorageService.privateDownload(id); } catch (BadRequestException e) { if (\"文件不存在或已被删除\".equals(e.getMessage())) { /* refresh the file list; do not retry the same id */ } }","preventionTips":["Always drive downloads from a freshly fetched list rather than cached ids/bookmarks.","Handle the 404-state in the UI with a friendly 'no longer available' message.","Clean up s3_storage rows in the same transaction/step as object deletion."],"tags":["s3","download","not-found","metadata"],"backgroundTag":null,"analyzedSha":"55fbf705956949697dbd68bf9003776609d3d029","analyzedAt":"2026-08-14T11:56:12.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}