{"record":{"id":"a5eb883193955676","repo":"qishibo/AnotherRedisDesktopManager","slug":"delete-batch-stream-on-error-e-message","errorCode":null,"errorMessage":"Delete Batch Stream On Error: ${e.message}","messagePattern":"Delete Batch Stream On Error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/components/DeleteBatch.vue","lineNumber":95,"sourceCode":"          count: 20000,\n        };\n\n        const stream = node.scanBufferStream(scanOption);\n        this.scanStreams.push(stream);\n\n        stream.on('data', (keys) => {\n          this.addToList(keys.sort());\n\n          // pause for dom rendering\n          stream.pause();\n          setTimeout(() => {\n            this.loadingScan && stream.resume();\n          }, 100);\n        });\n\n        stream.on('error', (e) => {\n          this.loadingScan = false;\n          this.$message.error({\n            message: `Delete Batch Stream On Error: ${e.message}`,\n            duration: 1500,\n          });\n        });\n\n        stream.on('end', () => {\n          // all nodes scan finished(cusor back to 0)\n          if (--this.scanningCount <= 0) {\n            this.loadingScan = false;\n            this.scanningEnd = true;\n          }\n        });\n      });\n    },\n    addToList(keys) {\n      const list = [];\n      for (const key of keys) {\n        list.push({ key, str: this.$util.bufToString(key) });","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/qishibo/AnotherRedisDesktopManager/blob/c149855106628babcdfb7675a8e7ba9434d2492a/src/components/DeleteBatch.vue#L77-L113","documentation":"The SCAN-based readable stream used by the batch-delete dialog emitted its 'error' event. Mid-scan failures come from the underlying connection or cluster: ECONNRESET, READONLY during failover, MOVED/IO errors when slots move in cluster mode, or the server closing the stream. The handler stops loadingScan and shows a 1.5s toast, but the already-scanned keys remain in the list.","triggerScenarios":"Scanning a huge keyspace when the connection drops; cluster resharding or master failover mid-scan; server/client idle timeout killing long SCAN iterations; LB cutting long-lived connections.","commonSituations":"Deleting millions of keys over VPN, cleanup jobs running during maintenance windows, scans outliving load-balancer idle timeouts.","solutions":["Reconnect and restart the batch delete; already-found keys remain listed so the retry is cheaper","Run long scans against a stable topology (no concurrent resharding/failover)","Tune SCAN COUNT and the pause interval so iterations finish before idle timeouts","Persist the cursor and resume from it instead of restarting from 0"],"exampleFix":"// before\nstream.on('error', (e) => {\n  this.loadingScan = false;\n  this.$message.error({ message: `Delete Batch Stream On Error: ${e.message}`, duration: 1500 });\n});\n\n// after\nstream.on('error', (e) => {\n  this.loadingScan = false;\n  stream.destroy();\n  this.$message.error({\n    message: `Delete Batch Stream On Error: ${e.message} (scanned ${this.allKeysList.length} keys, retry to continue)`,\n    duration: 3000,\n  });\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"stream.on('error', (e) => {\n  this.loadingScan = false;\n  stream.destroy(); // release cursor and socket bookkeeping\n  // keep already-collected keys so a retry can continue\n  this.$message.error(`Delete Batch Stream On Error: ${e.message}`);\n});","preventionTips":["Always listen for 'error' on readable streams or the process throws","Destroy the stream in the error handler","Track scanned keys/cursor so retries resume instead of restarting","Avoid long scans during cluster maintenance windows"],"tags":["redis","scan","scanstream","batch-delete","stream-error"],"backgroundTag":"redis-scan-stream-error","analyzedSha":"c149855106628babcdfb7675a8e7ba9434d2492a","analyzedAt":"2026-08-22T09:06:28.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}