Handle ERR_STREAM_UNABLE_TO_PIPE alongside ERR_STREAM_PREMATURE_CLOSE (#31174)

GitOrigin-RevId: bbf49237b177d7a58a9b13efc6f38f5eecfb745c
This commit is contained in:
Anna Claire Fields
2026-02-03 09:05:50 +00:00
committed by Copybot
parent a591f2eb7a
commit ee4b5f515c
8 changed files with 29 additions and 8 deletions
+5 -1
View File
@@ -68,7 +68,11 @@ function getFile(req, res, next) {
} }
pipeline(fileStream, res, err => { pipeline(fileStream, res, err => {
if (err && err.code === 'ERR_STREAM_PREMATURE_CLOSE') { if (
err &&
(err.code === 'ERR_STREAM_PREMATURE_CLOSE' ||
err.code === 'ERR_STREAM_UNABLE_TO_PIPE')
) {
res.end() res.end()
} else if (err) { } else if (err) {
next( next(
@@ -373,7 +373,10 @@ async function getProjectBlob(req, res, next) {
try { try {
await pipeline(stream, res) await pipeline(stream, res)
} catch (err) { } catch (err) {
if (err?.code === 'ERR_STREAM_PREMATURE_CLOSE') { if (
err?.code === 'ERR_STREAM_PREMATURE_CLOSE' ||
err?.code === 'ERR_STREAM_UNABLE_TO_PIPE'
) {
res.end() res.end()
} else { } else {
throw OError.tag(err, 'error transferring stream', { projectId, hash }) throw OError.tag(err, 'error transferring stream', { projectId, hash })
+1
View File
@@ -291,6 +291,7 @@ if (Settings.shutdownDrainTimeWindow) {
'EPIPE', 'EPIPE',
'ECONNRESET', 'ECONNRESET',
'ERR_STREAM_WRITE_AFTER_END', 'ERR_STREAM_WRITE_AFTER_END',
'ERR_STREAM_UNABLE_TO_PIPE',
].includes(error.code) || ].includes(error.code) ||
// socket.io error handler sending on polling connection again. // socket.io error handler sending on polling connection again.
(error.code === 'ERR_HTTP_HEADERS_SENT' && (error.code === 'ERR_HTTP_HEADERS_SENT' &&
+9 -2
View File
@@ -44,9 +44,16 @@ if (Settings.catchErrors) {
process.removeAllListeners('uncaughtException') process.removeAllListeners('uncaughtException')
process.removeAllListeners('unhandledRejection') process.removeAllListeners('unhandledRejection')
process process
.on('uncaughtException', error => .on('uncaughtException', error => {
if (error.code === 'ERR_STREAM_UNABLE_TO_PIPE') {
metrics.inc('disconnected_write', 1, { status: error.code })
return logger.warn(
{ err: error },
'attempted to write to disconnected client'
)
}
logger.error({ err: error }, 'uncaughtException') logger.error({ err: error }, 'uncaughtException')
) })
.on('unhandledRejection', (reason, p) => { .on('unhandledRejection', (reason, p) => {
logger.error({ err: reason }, 'unhandledRejection at Promise', p) logger.error({ err: reason }, 'unhandledRejection at Promise', p)
}) })
@@ -86,7 +86,8 @@ async function downloadFromCache(req, res) {
if ( if (
streamingStarted && streamingStarted &&
reqAborted && reqAborted &&
err.code === 'ERR_STREAM_PREMATURE_CLOSE' (err.code === 'ERR_STREAM_PREMATURE_CLOSE' ||
err.code === 'ERR_STREAM_UNABLE_TO_PIPE')
) { ) {
// Ignore noisy spurious error // Ignore noisy spurious error
return return
@@ -596,7 +596,8 @@ const _CompileController = {
if ( if (
streamingStarted && streamingStarted &&
reqAborted && reqAborted &&
err.code === 'ERR_STREAM_PREMATURE_CLOSE' (err.code === 'ERR_STREAM_PREMATURE_CLOSE' ||
err.code === 'ERR_STREAM_UNABLE_TO_PIPE')
) { ) {
// Ignore noisy spurious error // Ignore noisy spurious error
return return
@@ -91,7 +91,8 @@ async function getFile(req, res) {
if ( if (
err instanceof Error && err instanceof Error &&
'code' in err && 'code' in err &&
err.code === 'ERR_STREAM_PREMATURE_CLOSE' (err.code === 'ERR_STREAM_PREMATURE_CLOSE' ||
err.code === 'ERR_STREAM_UNABLE_TO_PIPE')
) { ) {
// Ignore clients closing the connection prematurely // Ignore clients closing the connection prematurely
return return
@@ -15,7 +15,10 @@ function serveStaticWrapper(root, options) {
return next() return next()
} }
if (error.code !== 'ERR_STREAM_PREMATURE_CLOSE') { if (
error.code !== 'ERR_STREAM_PREMATURE_CLOSE' &&
error.code !== 'ERR_STREAM_UNABLE_TO_PIPE'
) {
return next(error) return next(error)
} }