elunez/eladmin · warning · BadRequestException
文件不存在或已被删除
Error message
文件不存在或已被删除
What it means
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).
Source
Thrown at eladmin-tools/src/main/java/me/zhengjie/service/impl/S3StorageServiceImpl.java:179
map.put("文件名称", s3Storage.getFileName());
map.put("真实存储的名称", s3Storage.getFileRealName());
map.put("文件大小", s3Storage.getFileSize());
map.put("文件MIME 类型", s3Storage.getFileMimeType());
map.put("文件类型", s3Storage.getFileType());
map.put("文件路径", s3Storage.getFilePath());
map.put("创建者", s3Storage.getCreateBy());
map.put("更新者", s3Storage.getUpdateBy());
map.put("创建日期", s3Storage.getCreateTime());
map.put("更新时间", s3Storage.getUpdateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
public Map<String, String> privateDownload(Long id) {
S3Storage storage = s3StorageRepository.findById(id).orElse(null);
if (storage == null) {
throw new BadRequestException("文件不存在或已被删除");
}
// 创建 GetObjectRequest,指定存储桶和文件键
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(amzS3Config.getDefaultBucket())
.key(storage.getFilePath())
.build();
String base64Data;
// 使用 try-with-resources 确保流能被自动关闭
// s3Client.getObject() 返回一个 ResponseInputStream,它是一个包含S3对象数据的输入流
try (ResponseInputStream<GetObjectResponse> s3InputStream = s3Client.getObject(getObjectRequest)) {
// 使用 IOUtils.toByteArray 将输入流直接转换为字节数组
byte[] fileBytes = IOUtils.toByteArray(s3InputStream);
// 使用 Java 内置的 Base64 编码器将字节数组转换为 Base64 字符串
base64Data = Base64.getEncoder().encodeToString(fileBytes);
} catch (S3Exception e) {
// 处理 AWS 特定的异常
throw new BadRequestException("从 S3 下载文件时出错: " + e.awsErrorDetails().errorMessage());
} catch (IOException e) {View on GitHub (pinned to 55fbf70595)
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.
Example fix
// before
S3Storage storage = s3StorageRepository.findById(id).orElse(null);
if (storage == null) {
throw new BadRequestException("文件不存在或已被删除");
}
// after: use orElseThrow for the same behavior, less ceremony
S3Storage storage = s3StorageRepository.findById(id)
.orElseThrow(() -> new BadRequestException("文件不存在或已被删除")); Defensive patterns
Strategy: validation
Validate before calling
// caller-side existence check before requesting download
boolean exists = s3StorageRepository.existsById(id);
if (!exists) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("文件不存在或已被删除"); } Try / catch
try { s3StorageService.privateDownload(id); } catch (BadRequestException e) { if ("文件不存在或已被删除".equals(e.getMessage())) { /* refresh the file list; do not retry the same id */ } } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Frontend caching an old file list; concurrent deletion; bookmarked/download links persisted after cleanup jobs; id confusion between local storage and S3 storage tables.
Related errors
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/ce203ad39f3f4091.
Report an issue: GitHub.