Skip to Content
Jan 20 at 01:16 PM

Error when returning zip file from cap


Hello Experts,

In my project I am trying to return a .zip file (filled with multiple csv/xlsx/json documents) from an odata function. To do this I am accessing the underlying express response object and piping the generated zip file as a readable stream. When I do this in a pure express app it works fine, but when doing it through cap the file gets corrupted and I am unable to open it once downloaded. A full example repo is available here, below are the important parts:

//The function I am using to pip the zip file, res is the express response object.
// Definition is found in express/app.js in repo 
const loadResponse = async (res, type) => { 
  const content = await getZip(type); 
  res.set('Content-Type', 'application/zip'); 
  res.set('Content-Disposition', 'attachment; filename=""');
  const stream = new Readable(); 


  // Await stream finish before returning
  await new Promise((resolve, reject) => { 
    stream.on('end', resolve); 
    stream.on('error', err => reject(err)); 

// Three different implementations of the function above
// 1. Called from pure express app (in express/app.js)

app.get('/getCsv', async (req, res) => { 
  await loadResponse(res, 'csv'); // This works

// 2. Called from custom route on server start (server.js)
cds.once('bootstrap', app => { 
  app.get('/getZip', async function(req, res, next) { 
    await loadResponse(res, 'csv'); // Returns invalid file 

// 3. Called from service handler function (srv/my-service.js)
srv.on('getZip', async req => { 
  await loadResponse(req.context.http.res, 'csv'); // Returns invalid file 

Of the three examples above, the one when running a pure express app (number 1) returns the zip-file correctly, whereas both of the cap implementations return an invalid zip file that can't be opened. Any input as to why this might be would be much appreciated.

Best Regards,