#javascript #node.js #stream
#javascript #node.js #поток
Вопрос:
Существуют различные сообщения, посвященные общей проблеме тайм-аутов при использовании http.get(), но ни в одном из них, похоже, не рассматривается вопрос о том, как обращаться с тайм-аутами, возникающими во время самого потока, после того, как уже получен успешный ответ.
Возьмем этот код для примера. Он отправляет запрос на некоторый сервер, который отвечает вовремя, но создает искусственный тайм-аут во время потока:
(async()=>{
//Send request to a dummy server, that creates a timeout, IN THE MIDDLE OF THE STREAM.
const request =http.get('http://localhost/timeout/',async (res)=>{
const write = fs.createWriteStream('.text.txt');
try {
await pipelinePromisified(res,write);
console.log('Everything went fine')//Being that the timeout error during the stream is not caught by pipeline,
//the promise gets resolved..
} catch (error) {
//The error is NOT caught by pipeline!
console.log('Error from pipeline',error)
}
}).on('error',(e)=>{
//Error is caught here
console.log('error from request on error')
})
request.setTimeout(4000,()=>{
request.destroy(new Error('request timed out'));
//This causes the piping of the streams to stop in the middle(resulting a partial file), but the pipeline doesn't treat this is an error.
})
})()
Обратите внимание на ключевую проблему: время ожидания во время потока распознается, запрос уничтожается, входящее сообщение (ответ) прекращает перекачку данных, но конвейер не распознает это как ошибку.
В результате клиентский код не знает о том, что файл был частично загружен, поскольку ошибка не выдается.
Как справиться с этой ситуацией? В моем тестировании вызов response.emit(‘error’), похоже, решает эту проблему, но в документах узла четко указано, что этого делать нельзя.
Любая помощь будет принята с благодарностью.
Обновление: похоже, что на узле 12 (у меня установлены 10 и 12 через nvm) ошибка обнаруживается конвейером, но не в узле 10.