{"record":{"id":"dad6f552f5da0866","repo":"Billionmail/BillionMail","slug":"failed-to-insert-alias-v","errorCode":null,"errorMessage":"failed to insert alias: %v","messagePattern":"failed to insert alias: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/domains/domains.go","lineNumber":75,"sourceCode":"\t\t\t_, err = g.DB().Model(\"alias\").\n\t\t\t\tWhere(\"address\", address).\n\t\t\t\tWhere(\"domain\", domainName).\n\t\t\t\tData(g.Map{\"goto\": catchall, \"active\": 1, \"update_time\": time.Now().Unix()}).\n\t\t\t\tUpdate()\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to update alias: %v\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t_, err = g.DB().Model(\"alias\").Data(g.Map{\n\t\t\t\t\"address\":     address,\n\t\t\t\t\"goto\":        catchall,\n\t\t\t\t\"domain\":      domainName,\n\t\t\t\t\"active\":      1,\n\t\t\t\t\"create_time\": time.Now().Unix(),\n\t\t\t\t\"update_time\": time.Now().Unix(),\n\t\t\t}).Insert()\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to insert alias: %v\", err)\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// catchall is empty, disabled\n\t\t_, _ = g.DB().Model(\"alias\").\n\t\t\tWhere(\"address\", address).\n\t\t\tWhere(\"domain\", domainName).\n\t\t\tData(g.Map{\"active\": 0, \"update_time\": time.Now().Unix()}).\n\t\t\tUpdate()\n\t}\n\treturn nil\n}\n\nfunc Add(ctx context.Context, domain *v1.Domain) error {\n\tdomain.CreateTime = time.Now().Unix()\n\tdomain.Active = 1\n\n\t_, err := g.DB().Model(\"domain\").Ctx(ctx).Insert(domain)","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/domains/domains.go#L57-L93","documentation":"setCatchall wraps an INSERT into the `alias` table when the catchall alias row does not yet exist and must be created. The wrapped error is the raw GoFrame/PostgreSQL insert failure, annotated so callers of Add/Update know the catchall creation step failed.","triggerScenarios":"domains.Add or domains.Update with a non-empty Catchall, when no alias row exists for the domain (count query returned 0) and the INSERT of (address, goto, domain, active, create_time, update_time) fails — DB unreachable, NOT NULL/unique violation, or permission denied on INSERT.","commonSituations":"First-time domain creation while Postgres is down; duplicate alias address violating a unique index; DB role missing INSERT privilege; malformed domain name producing an invalid address value.","solutions":["Check the wrapped driver error: connection issues first (is Postgres up?), then SQL syntax/constraint messages","Ensure a unique index on alias.address and that no conflicting row exists","Grant INSERT privilege on alias to the application DB user","Retry the domain Add/Update after the DB is healthy"],"exampleFix":"// before\n_, err = g.DB().Model(\"alias\").Data(g.Map{...}).Insert()\n// after\n_, err = g.DB().Model(\"alias\").Data(g.Map{...}).Save() // upsert to tolerate existing row\nif err != nil { return fmt.Errorf(\"failed to insert alias: %v\", err) }","handlingStrategy":"validation","validationCode":"dup, _ := g.DB().Model(\"alias\").Where(\"address\", address).Count()\nif dup > 0 { return nil } // already exists, skip insert\nif catchall == \"\" { return errors.New(\"catchall must be non-empty\") }","typeGuard":null,"tryCatchPattern":"_, err := g.DB().Model(\"alias\").Data(g.Map{...}).Insert()\nif err != nil {\n    if strings.Contains(err.Error(), \"duplicate key\") { return g.DB().Model(\"alias\").Where(\"address\", address).Data(g.Map{\"goto\": catchall}).Update() }\n    return fmt.Errorf(\"failed to insert alias: %v\", err)\n}","preventionTips":["Use Save()/upsert semantics instead of blind Insert","Validate domain names before composing the alias address","Grant INSERT/UPDATE on alias to the app DB role in deployment scripts","Add a unique constraint and handle it explicitly rather than letting inserts fail"],"tags":["database","postgresql","goframe","insert","alias"],"backgroundTag":"database-insert-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"}