{"record":{"id":"221768ffc6e053a9","repo":"qishibo/AnotherRedisDesktopManager","slug":"persist-error-e-message","errorCode":null,"errorMessage":"Persist Error: ${e.message}","messagePattern":"Persist Error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/components/KeyHeader.vue","lineNumber":230,"sourceCode":"            message: this.$t('message.modify_success'),\n            duration: 1000,\n          });\n\n          if (keyDeleted) {\n            this.refreshKeyList(this.redisKey);\n            this.$bus.$emit('removePreTab');\n          }\n        }\n      }).catch((e) => {\n        this.$message.error(`Expire Error: ${e.message}`);\n      });\n    },\n    persistKey() {\n      this.client.persist(this.redisKey).then(() => {\n        this.initShow();\n        this.$message.success(this.$t('message.modify_success'));\n      }).catch((e) => {\n        this.$message.error(`Persist Error: ${e.message}`);\n      });\n    },\n    refreshKeyList(key, type = 'del') {\n      this.$bus.$emit('refreshKeyList', this.client, key, type);\n    },\n    initShortcut() {\n      // refresh\n      this.$shortcut.bind('ctrl+r, ⌘+r, f5', this.hotKeyScope, () => {\n        // make input blur first\n        this.$refs.deleteBtn.$el.focus();\n        this.refreshKey();\n\n        return false;\n      });\n      // delete\n      this.$shortcut.bind('ctrl+d, ⌘+d', this.hotKeyScope, () => {\n        this.deleteKey();\n        return false;","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/qishibo/AnotherRedisDesktopManager/blob/c149855106628babcdfb7675a8e7ba9434d2492a/src/components/KeyHeader.vue#L212-L248","documentation":"Wraps a rejection of the Redis PERSIST command issued by persistKey() (this.client.persist(this.redisKey)), which strips the TTL from the current key. PERSIST never rejects for a missing key (it resolves 0), so a rejection means the command could not run or complete: the connection is down/reconnecting, auth is wrong (NOAUTH / ERR invalid password), the target is a read-only replica (READONLY), or the client flushed its command queue on disconnect. The raw driver message is appended so the exact cause stays visible.","triggerScenarios":"Clicking the remove-TTL (persist) action in the key header right after the socket dropped (sleep/resume, VPN switch); issuing it against a replica with replica-read-only yes; after the Redis password was rotated so queued commands fail with NOAUTH; server restarted mid-request.","commonSituations":"Laptop sleep/resume killing idle TCP sockets, load balancers/firewalls reaping idle connections, managed Redis (ElastiCache/Azure) endpoints mid-failover, read-replica connections used for writes.","solutions":["Confirm the connection is healthy before issuing the command: check client.status === 'ready' or run a PING; reconnect if not","If auth changed, edit the saved connection password and reconnect (NOAUTH / ERR invalid password)","If targeting a replica, connect to the primary or set replica-read-only no on the server","Keep the .catch and map known messages (NOAUTH, READONLY, ECONNRESET) to actionable UI text with a reconnect action"],"exampleFix":"// before\nthis.client.persist(this.redisKey).then(() => {\n  this.initShow();\n}).catch((e) => {\n  this.$message.error(`Persist Error: ${e.message}`);\n});\n\n// after\nif (this.client.status !== 'ready') {\n  this.$message.error(this.$t('message.not_connected'));\n  return;\n}\nthis.client.persist(this.redisKey).then(() => {\n  this.initShow();\n}).catch((e) => {\n  const msg = /NOAUTH|invalid password/i.test(e.message) ? this.$t('message.auth_failed')\n    : /READONLY/i.test(e.message) ? this.$t('message.readonly_replica')\n    : e.message;\n  this.$message.error(`Persist Error: ${msg}`);\n});","handlingStrategy":"try-catch","validationCode":"if (this.client.status !== 'ready') {\n  this.$message.error(this.$t('message.not_connected'));\n  return;\n}","typeGuard":null,"tryCatchPattern":".catch((e) => {\n  const m = String(e.message || e);\n  if (/NOAUTH|invalid password/i.test(m)) { /* prompt re-auth */ }\n  else if (/READONLY/i.test(m)) { /* route to primary */ }\n  else if (/ECONNRESET|ECONNREFUSED|closed/i.test(m)) { /* reconnect and retry */ }\n  else { this.$message.error(`Persist Error: ${m}`); }\n})","preventionTips":["Check client.status before fire-and-forget writes","Attach a reconnect handler so sockets recover after sleep/resume","Keep auth config in sync when the server password rotates","Never write to read replicas unless replica-read-only no is set"],"tags":["redis","persist","ttl","node-redis","promise-rejection"],"backgroundTag":"redis-command-failed","analyzedSha":"c149855106628babcdfb7675a8e7ba9434d2492a","analyzedAt":"2026-08-22T09:06:28.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}