Ответ от jfriend00 указал мне правильное направление. Вот два разных способа, которыми я решил это. Мне нужна функция, которая возвращает поток, а не обрабатывает ошибку в функции обработчика req. Это больше похоже на то, что я на самом деле делаю в реальном коде.
Обработка ошибки из потока:
Как и выше, за исключением того, что я позаботился о том, чтобы вручную уничтожить поток. Правильно ли это заботится о дескрипторе внутреннего файла? Я думаю, что это так.
const server = createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'application/json'
})
getStream().pipe(res)
})
function getStream() {
const stream = createReadStream(`not-here.json`, {
autoClose: false,
encoding: 'utf8'
})
stream.on('error', err => {
// handling "no such file" errors
if (err.code === 'ENOENT') {
// push JSON data to stream
stream.push(JSON.stringify({data: [1,2,3,4,5]}))
// signal the end of stream
stream.push(null)
}
// destory/close the stream regardless of error
stream.destroy()
console.error(err)
})
return stream
}
Обработка ошибки при открытии файла:
Как подсказывает jfriend00.
const { promisify } = require('util')
const { Readable } = require('stream')
const { open, createReadStream } = require('fs')
const openAsync = promisify(open)
const server = createServer(async (req, res) => {
res.writeHead(200, {
'Content-Type': 'application/json'
})
const stream = await getStream()
stream.pipe(res)
})
async function getStream() {
try {
const fd = await openAsync(`not-here.json`)
return createReadStream(null, {fd, encoding: 'utf8'})
} catch (error) {
console.log(error)
// setup new stream
const stream = new Readable()
// push JSON data to stream
stream.push(JSON.stringify({data: [1,2,3,4,5]}))
// signal the end of stream
stream.push(null)
return stream
}
}
Мне все еще нравится обрабатыватьв потоке лучше, но хотелось бы услышать причины, по которым вы можете сделать это так или иначе.