Просмотр исходного кода

Handle ERR_STREAM_UNABLE_TO_PIPE alongside ERR_STREAM_PREMATURE_CLOSE (#31174)

GitOrigin-RevId: bbf49237b177d7a58a9b13efc6f38f5eecfb745c
Anna Claire Fields 6 месяцев назад
Родитель
Сommit
ee4b5f515c

+ 5 - 1
services/filestore/app/js/FileController.js

@@ -68,7 +68,11 @@ function getFile(req, res, next) {
       }
 
       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()
         } else if (err) {
           next(

+ 4 - 1
services/history-v1/api/controllers/projects.js

@@ -373,7 +373,10 @@ async function getProjectBlob(req, res, next) {
     try {
       await pipeline(stream, res)
     } 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()
       } else {
         throw OError.tag(err, 'error transferring stream', { projectId, hash })

+ 1 - 0
services/real-time/app.js

@@ -291,6 +291,7 @@ if (Settings.shutdownDrainTimeWindow) {
           'EPIPE',
           'ECONNRESET',
           'ERR_STREAM_WRITE_AFTER_END',
+          'ERR_STREAM_UNABLE_TO_PIPE',
         ].includes(error.code) ||
         // socket.io error handler sending on polling connection again.
         (error.code === 'ERR_HTTP_HEADERS_SENT' &&

+ 9 - 2
services/web/app.mjs

@@ -44,9 +44,16 @@ if (Settings.catchErrors) {
   process.removeAllListeners('uncaughtException')
   process.removeAllListeners('unhandledRejection')
   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')
-    )
+    })
     .on('unhandledRejection', (reason, p) => {
       logger.error({ err: reason }, 'unhandledRejection at Promise', p)
     })

+ 2 - 1
services/web/app/src/Features/Compile/ClsiCacheController.mjs

@@ -86,7 +86,8 @@ async function downloadFromCache(req, res) {
     if (
       streamingStarted &&
       reqAborted &&
-      err.code === 'ERR_STREAM_PREMATURE_CLOSE'
+      (err.code === 'ERR_STREAM_PREMATURE_CLOSE' ||
+        err.code === 'ERR_STREAM_UNABLE_TO_PIPE')
     ) {
       // Ignore noisy spurious error
       return

+ 2 - 1
services/web/app/src/Features/Compile/CompileController.mjs

@@ -596,7 +596,8 @@ const _CompileController = {
       if (
         streamingStarted &&
         reqAborted &&
-        err.code === 'ERR_STREAM_PREMATURE_CLOSE'
+        (err.code === 'ERR_STREAM_PREMATURE_CLOSE' ||
+          err.code === 'ERR_STREAM_UNABLE_TO_PIPE')
       ) {
         // Ignore noisy spurious error
         return

+ 2 - 1
services/web/app/src/Features/FileStore/FileStoreController.mjs

@@ -91,7 +91,8 @@ async function getFile(req, res) {
     if (
       err instanceof Error &&
       '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
       return

+ 4 - 1
services/web/app/src/infrastructure/ServeStaticWrapper.mjs

@@ -15,7 +15,10 @@ function serveStaticWrapper(root, options) {
         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)
       }