elunez/eladmin · error · BadRequestException
上传失败
Error message
上传失败
What it means
Thrown by LocalStorageServiceImpl.create when FileUtil.upload(multipartFile, path) returns null after the size check passed — hutool's FileUtil.upload returns null on IOException while writing the multipart file to disk under properties.getPath().getPath() + type + separator. So the file exceeded maxSize it would have thrown earlier (a different exception); this specific error means a disk-level write failure.
Source
Thrown at eladmin-tools/src/main/java/me/zhengjie/service/impl/LocalStorageServiceImpl.java:80
return localStorageMapper.toDto(localStorageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public LocalStorageDto findById(Long id){
LocalStorage localStorage = localStorageRepository.findById(id).orElseGet(LocalStorage::new);
ValidationUtil.isNull(localStorage.getId(),"LocalStorage","id",id);
return localStorageMapper.toDto(localStorage);
}
@Override
@Transactional(rollbackFor = Exception.class)
public LocalStorage create(String name, MultipartFile multipartFile) {
FileUtil.checkSize(properties.getMaxSize(), multipartFile.getSize());
String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
String type = FileUtil.getFileType(suffix);
File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type + File.separator);
if(ObjectUtil.isNull(file)){
throw new BadRequestException("上传失败");
}
try {
name = StringUtils.isBlank(name) ? FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename()) : name;
LocalStorage localStorage = new LocalStorage(
file.getName(),
name,
suffix,
file.getPath(),
type,
FileUtil.getSize(multipartFile.getSize())
);
return localStorageRepository.save(localStorage);
}catch (Exception e){
FileUtil.del(file);
throw e;
}
}
View on GitHub (pinned to 55fbf70595)
Solutions
- Check the configured storage path (LocalStorage properties, e.g. files.path in application.yml) exists and is writable by the JVM process user (touch test).
- Free disk space / raise quota if the volume is full (df -h).
- In containers, mount a writable volume at the configured path and ensure the run user owns it.
- Confirm directory creation: FileUtil.upload expects the base type directories to be creatable — pre-create `<path>/image`, `<path>/doc`, etc. or grant mkdir rights.
- Inspect logs for the underlying IOException swallowed by FileUtil.upload's null return.
Example fix
// before
File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type + File.separator);
if(ObjectUtil.isNull(file)){
throw new BadRequestException("上传失败");
}
// after: write explicitly and fail with the real cause
File dir = new File(properties.getPath().getPath(), type);
if(!dir.exists() && !dir.mkdirs()){
throw new BadRequestException("存储目录创建失败: " + dir.getAbsolutePath());
}
File file = null;
try {
file = new File(dir, IdUtil.simpleUUID() + "." + suffix);
multipartFile.transferTo(file);
} catch (IOException e) {
throw new BadRequestException("上传失败: " + e.getMessage());
} Defensive patterns
Strategy: validation
Validate before calling
// startup sanity: storage root must be writable
File root = new File(properties.getPath().getPath());
if (!root.exists() && !root.mkdirs()) throw new IllegalStateException("storage path not creatable: " + root);
if (!root.canWrite()) throw new IllegalStateException("storage path not writable: " + root); Try / catch
try { localStorageService.create(name, file); } catch (BadRequestException e) { if ("上传失败".equals(e.getMessage())) { /* disk/permission issue: check volume, do not retry the same upload blindly */ } } Prevention
- Mount a writable volume at the configured files.path in containers and chown it to the run user.
- Disk-space alerts on the storage volume — FileUtil.upload returns null on IO failure.
- Pre-create type subdirectories (image/doc/media/...) at deploy time.
When it happens
Trigger: POST /localStorage (file upload) or POST /localStorage/pictures where the target directory configured by LocalStorage properties (files.path) does not exist or is not writable; disk full; container read-only filesystem; path with insufficient permissions for the JVM user.
Common situations: Default './file' path not created in the deployment dir; Docker image running as non-root with no write access to the mounted volume; disk quota exhausted; SELinux denying writes; path property changed to a location that isn't mounted.
Related errors
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/d21e28fce7eea0aa.
Report an issue: GitHub.