{"record":{"id":"c16a0b53f72a3f07","repo":"Billionmail/BillionMail","slug":"failed-to-get-the-exception-recipient-list-w","errorCode":null,"errorMessage":"Failed to get the exception recipient list: %w","messagePattern":"Failed to get the exception recipient list: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/abnormal_recipient/abnormal_recipient.go","lineNumber":42,"sourceCode":"\tif keyword != \"\" {\n\t\tmodel = model.WhereLike(\"recipient\", \"%\"+keyword+\"%\")\n\t}\n\tif addType > 0 {\n\t\tmodel = model.Where(\"add_type\", addType)\n\t}\n\n\ttotal, err = model.Count()\n\tif err != nil {\n\t\treturn 0, nil, fmt.Errorf(\"Failed to get the total number of exception recipients: %w\", err)\n\t}\n\n\tlist = make([]*entity.AbnormalRecipient, 0)\n\terr = model.Page(page, pageSize).\n\t\tOrder(\"create_time DESC\").\n\t\tScan(&list)\n\n\tif err != nil {\n\t\treturn 0, nil, fmt.Errorf(\"Failed to get the exception recipient list: %w\", err)\n\t}\n\n\treturn total, list, nil\n}\n\nfunc Add(ctx context.Context, recipient string) error {\n\n\tnow := time.Now().Unix()\n\t_, err := g.DB().Model(\"abnormal_recipient\").\n\t\tData(g.Map{\n\t\t\t\"recipient\":   recipient,\n\t\t\t\"count\":       3,\n\t\t\t\"add_type\":    1,\n\t\t\t\"description\": \"Manually added\",\n\t\t\t\"create_time\": now,\n\t\t}).\n\t\tInsertIgnore()\n","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/abnormal_recipient/abnormal_recipient.go#L24-L60","documentation":"After counting, GetListWithPage fetches one page of abnormal recipients ordered by create_time DESC; a Scan failure is wrapped as 'Failed to get the exception recipient list'. Like the count error, this indicates a database read failure on the list query.","triggerScenarios":"ListAbnormalRecipient with valid pagination while the page/order Scan fails: DB unreachable, table missing, or row data that cannot be scanned into entity.AbnormalRecipient (schema/type mismatch after migration).","commonSituations":"Schema drift where a column type changed and scanning fails; transient connection drop between Count and Scan; missing table on a fresh environment; corrupted rows.","solutions":["Inspect the wrapped %w error — 'sql: no rows' variants vs connection vs scan-type errors need different fixes.","Run migrations to reconcile the entity.AbnormalRecipient struct with the actual table schema.","Check DB connectivity and retry if the failure was transient.","Compare entity field types against the table columns if the error mentions scan/conversion."],"exampleFix":"// before\nerr = model.Page(page, pageSize).Order(\"create_time DESC\").Scan(&list)\nif err != nil { return 0, nil, fmt.Errorf(\"Failed to get the exception recipient list: %w\", err) }\n// after\nif err := model.Page(page, pageSize).Order(\"create_time DESC\").Scan(&list); err != nil {\n    return 0, nil, fmt.Errorf(\"Failed to get the exception recipient list (page=%d, size=%d): %w\", page, pageSize, err)\n}","handlingStrategy":"try-catch","validationCode":"// validate pagination inputs before the call\nif page < 1 || pageSize < 1 || pageSize > 500 {\n  return errors.New(\"invalid pagination parameters\")\n}","typeGuard":null,"tryCatchPattern":"total, list, err := abnormal_recipient.GetListWithPage(ctx, page, pageSize, addType)\nif err != nil {\n  if isTransientDBError(err) { // timeouts, connection resets\n    return retryWithBackoff(3, func() error { _, _, err = GetListWithPage(...); return err })\n  }\n  return err\n}","preventionTips":["Keep entity.AbnormalRecipient in sync with table schema via migrations","Distinguish transient (retry) from permanent (schema) DB errors","Clamp pageSize to reasonable bounds to avoid heavy scans","Alert on DB error rates for list endpoints"],"tags":["database","postgres","query","pagination"],"backgroundTag":"database-query-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}