I'm querying a SQL server from an express api using the node-mssql module, and piping the rows (with some intermediate steps) to the response stream. I want to avoid writing headers until I know that the query won't produce an error before any rows, so that I can send a useful error message to the client instead of terminating the stream with the express default handler. However, express is writing default headers at some point that I'm having trouble identifying.
I've tried writing headers in a .once('data',) listener in the pipeline but at that point some default behavior has written headers for me and this produces an error.
let request = await new sql.Request(pool);
res.writeHead(200, {
'Transfer-Encoding': 'chunked',
'charset' : 'utf-8',
'Content-Type': 'application/json',
'Content-Encoding': 'gzip'
})
ndjsonStream.on('error', next)
request.pipe(ndjsonStream)
.pipe(transformer)
.pipe(gzip)
.pipe(res);
The above works but doesn't let me pass a useful error message.
let request = await new sql.Request(pool);
ndjsonStream.once('data', () => {
res.writeHead(200, {
'Transfer-Encoding': 'chunked',
'charset' : 'utf-8',
'Content-Type': 'application/json',
'Content-Encoding': 'gzip'
})
})
ndjsonStream.on('error', next)
request.pipe(ndjsonStream)
.pipe(transformer)
.pipe(gzip)
.pipe(res);
request.query(query);
This produces an error because express has helpfully written some headers for me before this listener fires i.e. content-type: text/html.
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client