2017-04-04 144 views
2

我在我的Cassandra数据库中有数百万行,我想在一个zip文件中将数据流传输到客户端(不希望在记忆)。我使用Cassandra-Node驱动程序中的stream()函数,通过管道传输到一个Transformer,该Transformer从我关心的每一行中提取一个字段并追加一个换行符,并通过管道将哪些管道归档到Express Response对象。这似乎工作正常,但我不知道如何正确处理流中的错误。我必须在为客户端流式传输之前设置适当的标题/状态,但是如果在流式传输过程中出现错误(例如在dbStream中),我想清理所有管道并将响应状态重置为404但是如果我在设置标题并开始流式传输之后尝试重置状态,我会得到Can't set headers after they are sent。我查看了所有结果,并且无法在管道/流式传输到Response对象时找到如何正确处理Node中的错误。如果我无法发送错误的正确响应代码,客户端如何才能知道有效数据是否实际流式传输?谁能帮忙?Node.js流/管道错误处理(更改错误响应状态)

function streamNamesToWriteStream(query, res, options) { 
    return new Promise((resolve, reject) => { 

    let success = true; 

    const dbStream = db.client.stream(query); 
    const rowTransformer = new Transform({ 
     objectMode: true, 
     transform(row, encoding, callback) { 
     try { 
      const vote = row.name + '\n'; 
      callback(null, vote); 
     } catch (err) { 
      callback(null, err.message + '\n'); 
     } 
     } 
    }); 

    // Handle res events 
    res.on('error', (err) => { 
     logger.error(`res ${res} error`); 
     return reject(err); 
    }); 

    dbStream.on('error', function(err) { 
     res.status(404).send() // Can't set headers after they are sent. 
     logger.debug(`dbStream error: ${err}`); 
     success = false; 
     //res.end(); 
     //return reject(err); 
    }); 

    res.writeHead(200, { 
     'Content-Type': 'application/zip', 
     'Content-disposition': 'attachment; filename=myFile.zip' 
    }); 

    const archive = archiver.create('zip'); 
    archive.on('error', function(err) { throw err; }); 
    archive.on('end', function(err) { 
     logger.debug(`Archive done`); 
     //res.status(404).end() 
    }); 

    archive.pipe(res, { 
     //end:false 
    }); 
    archive.append(dbStream.pipe(rowTransformer), { name: 'file1.txt' }); 
    archive.append(dbStream.pipe(rowTransformer), { name: 'file1.txt' }); 
    archive.finalize(); 
    }); 
} 
+0

这是一个有趣的问题。损坏的下载在HTTP/TCP工作方式中是固有的(因此在下载之后使哈希可用于验证的流行)。期待别人的建议。 –

回答

3

很明显,改变头文件为时已晚,所以必须有应用程序逻辑来检测问题。以下是我的一些想法:

  1. 当发生错误时,在流末尾写一些明确的哨兵。然后,zip文件的使用者需要查找该值来检查问题。

  2. 也许更简单的是让消费者对zip压缩文件的完整性进行验证。据推测,如果流失败,则压缩文件将被损坏。