elunez/eladmin · error · BadRequestException

打包失败

Error message

打包失败

What it means

GeneratorServiceImpl.download catches IOException around GenUtil.download + ZipUtil.zip + FileUtil.downloadFile and rethrows as BadRequestException('打包失败'). It means the server failed to render templates to a temp dir, zip it, or stream the zip to the response — an I/O or environment problem, not a config problem.

Source

Thrown at eladmin-generator/src/main/java/me/zhengjie/service/impl/GeneratorServiceImpl.java:202

        if (genConfig.getId() == null) {
            throw new BadRequestException(CONFIG_MESSAGE);
        }
        List<Map<String, Object>> genList = GenUtil.preview(columns, genConfig);
        return new ResponseEntity<>(genList, HttpStatus.OK);
    }

    @Override
    public void download(GenConfig genConfig, List<ColumnInfo> columns, HttpServletRequest request, HttpServletResponse response) {
        if (genConfig.getId() == null) {
            throw new BadRequestException(CONFIG_MESSAGE);
        }
        try {
            File file = new File(GenUtil.download(columns, genConfig));
            String zipPath = file.getPath() + ".zip";
            ZipUtil.zip(file.getPath(), zipPath);
            FileUtil.downloadFile(request, response, new File(zipPath), true);
        } catch (IOException e) {
            throw new BadRequestException("打包失败");
        }
    }
}

View on GitHub (pinned to 55fbf70595)

Solutions

  1. Check the server log for the underlying IOException to find the failing step (render, zip, or stream).
  2. Ensure the process user can write to the directory GenUtil.download uses (typically the configured path or a temp dir) — chmod/chown or mount a writable volume.
  3. Free disk space and retry the download.
  4. Retry with a stable connection / avoid cancelling; a client abort also surfaces here.

Example fix

# before: read-only container filesystem
 docker run eladmin ... (no writable tmp)

# after: mount writable tmp and output volumes
 docker run -v /data/codegen:/opt/codegen -e TMPDIR=/data/tmp eladmin ...
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check temp/output writability and disk headroom before download
File tmp = new File(System.getProperty("java.io.tmpdir"));
if (!tmp.canWrite() || tmp.getUsableSpace() < 256L * 1024 * 1024) {
    throw new IllegalStateException("tmp unwritable or low disk");
}
generatorService.download(config, columns, request, response);

Type guard

boolean environmentCanZip() {
    File tmp = new File(System.getProperty("java.io.tmpdir"));
    return tmp.canWrite() && tmp.getUsableSpace() > 100L * 1024 * 1024;
}

Try / catch

try {
    generatorService.download(config, columns, request, response);
} catch (BadRequestException e) {
    if ("打包失败".equals(e.getMessage())) {
        log.error("zip/download IO failure for {}", config.getTableName()); // server log has root cause
    }
    throw e;
}

Prevention

When it happens

Trigger: type=2 download when the temp/output directory is not writable, disk is full while zipping, the response stream is aborted by the client, or GenUtil.download cannot create the generation directory.

Common situations: Service account lacking write permission on the working/temp dir (common when running under systemd with ProtectSystem, or in Docker read-only layers); low disk space; client cancelling the download mid-stream; eladmin temp dir removed concurrently.

Related errors


AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14). Data as JSON: /api/errors/574f9efac1a1ee9d. Report an issue: GitHub.