{"record":{"id":"f4a3b22709a263be","repo":"yikart/AiToEarn","slug":"error-f4a3b2","errorCode":null,"errorMessage":"系统错误","messagePattern":"系统错误","errorType":"http","errorClass":"HttpException","httpStatus":500,"severity":"error","filePath":"project/aitoearn-electron/server/src/lib/wx/wxPay.service.ts","lineNumber":154,"sourceCode":"      batch_remark: '提现红包',\n      total_amount: transAmount * 100,\n      total_num: 1,\n      transfer_detail_list: [\n        {\n          out_detail_no: outBizNo,\n          transfer_amount: transAmount * 100,\n          transfer_remark: '提现红包',\n          openid: openId,\n        },\n      ],\n    });\n\n    if (result.status === 200) {\n      return result;\n    } else if (result.error === 'SYSTEM_ERROR' && result.status === 500) {\n      Logger.error('系统错误', 'SYSTEM_ERROR', 'wxPayService', result);\n      if (retry > 5) {\n        throw new HttpException('系统错误', HttpStatus.INTERNAL_SERVER_ERROR);\n      }\n      await sleep((retry + 1) * 1000);\n      return await this.sendRedPacket(\n        openId,\n        transAmount,\n        outBizNo,\n        (retry = retry + 1),\n      );\n    } else {\n      Logger.error('系统错误', 'wxPayService', result);\n      return null;\n    }\n  }\n}\n","sourceCodeStart":136,"sourceCodeEnd":169,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/lib/wx/wxPay.service.ts#L136-L169","documentation":"sendRedPacket calls WeChat Pay via a third-party relay that returns SYSTEM_ERROR with status 500. The service retries with increasing backoff (1s, 2s, ...), and once retry exceeds 5 it gives up and throws HttpException('系统错误', 500). This means the WeChat red-packet endpoint kept failing server-side through all retries.","triggerScenarios":"Calling sendRedPacket when the upstream WeChat/relay API responds { error: 'SYSTEM_ERROR', status: 500 } for more than 5 consecutive retries (retry counter > 5).","commonSituations":"WeChat Pay merchant-side outage; invalid or unbound merchant configuration for red packets; insufficient merchant balance; upstream relay service degraded — all causing persistent 500s instead of transient ones.","solutions":["Inspect the logged `result` payload (Logger.error includes it) for the upstream error detail","Increase retry count or backoff if the outage is expected to be transient","Verify WeChat Pay merchant config (mchid, API certs, red-packet product enabled, balance)","Add a circuit breaker so repeated SYSTEM_ERROR fails fast instead of retrying 5 times","Surface a user-facing message distinct from generic '系统错误' when retries are exhausted"],"exampleFix":"// before\nif (retry > 5) {\n  throw new HttpException('系统错误', HttpStatus.INTERNAL_SERVER_ERROR);\n}\n// after\nif (retry > 5) {\n  Logger.error(`sendRedPacket failed after ${retry} retries`, JSON.stringify(result), 'wxPayService');\n  throw new HttpException('微信红包发送失败，请稍后重试或联系客服', HttpStatus.BAD_GATEWAY);\n}","handlingStrategy":"retry","validationCode":"if (!openId || !transAmount || transAmount <= 0) {\n  throw new Error('sendRedPacket requires openId and a positive transAmount');\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await wxPayService.sendRedPacket(openId, amount, outBizNo);\n} catch (err) {\n  if (err instanceof HttpException && err.getStatus() === 500) {\n    // check outBizNo for duplicate before manual retry to avoid double payout\n  }\n  throw err;\n}","preventionTips":["Keep outBizNo idempotent so manual retries never double-pay","Verify WeChat merchant config and balance before sending red packets","Cap retry attempts with exponential backoff and alert on exhaustion","Monitor upstream 500 rates and trip a circuit breaker"],"tags":["wechat-pay","retry","upstream","http-500"],"backgroundTag":"upstream-system-error","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}