{"record":{"id":"2a185237234038e2","repo":"krahets/hello-algo","slug":"error-2a1852","errorCode":null,"errorMessage":"error","messagePattern":"error","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"codes/go/chapter_graph/graph_adjacency_list.go","lineNumber":45,"sourceCode":"\tfor _, edge := range edges {\n\t\tg.addVertex(edge[0])\n\t\tg.addVertex(edge[1])\n\t\tg.addEdge(edge[0], edge[1])\n\t}\n\treturn g\n}\n\n/* 获取顶点数量 */\nfunc (g *graphAdjList) size() int {\n\treturn len(g.adjList)\n}\n\n/* 添加边 */\nfunc (g *graphAdjList) addEdge(vet1 Vertex, vet2 Vertex) {\n\t_, ok1 := g.adjList[vet1]\n\t_, ok2 := g.adjList[vet2]\n\tif !ok1 || !ok2 || vet1 == vet2 {\n\t\tpanic(\"error\")\n\t}\n\t// 添加边 vet1 - vet2, 添加匿名 struct{},\n\tg.adjList[vet1] = append(g.adjList[vet1], vet2)\n\tg.adjList[vet2] = append(g.adjList[vet2], vet1)\n}\n\n/* 删除边 */\nfunc (g *graphAdjList) removeEdge(vet1 Vertex, vet2 Vertex) {\n\t_, ok1 := g.adjList[vet1]\n\t_, ok2 := g.adjList[vet2]\n\tif !ok1 || !ok2 || vet1 == vet2 {\n\t\tpanic(\"error\")\n\t}\n\t// 删除边 vet1 - vet2\n\tg.adjList[vet1] = DeleteSliceElms(g.adjList[vet1], vet2)\n\tg.adjList[vet2] = DeleteSliceElms(g.adjList[vet2], vet1)\n}\n","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/codes/go/chapter_graph/graph_adjacency_list.go#L27-L63","documentation":"`addEdge(vet1, vet2)` in the undirected `graphAdjList` panics with \"error\" when an endpoint is not present in the adjacency map, or when the two endpoints are identical. The book's model forbids self-loops and requires both vertices to already exist, so `!ok1 || !ok2 || vet1 == vet2` is treated as a programming error.","triggerScenarios":"Calling `addEdge` for a vertex never added via `addVertex`; calling `addEdge(v, v)`; building an edge before its vertices are registered.","commonSituations":"Loading an edge list whose endpoints were not pre-loaded, JSON/CSV input containing self-loops, or a typo so both endpoints compare unequal but one is unknown.","solutions":["Register both endpoints with `addVertex` before `addEdge`.","Filter self-loops out of input before inserting (`vet1 != vet2`).","Add a `hasVertex` helper and assert both endpoints exist first.","Recover around bulk edge insertion when data is untrusted."],"exampleFix":"// before\ng.addEdge(a, b) // panic if a or b missing, or a == b\n\n// after\nif hasVertex(g, a) && hasVertex(g, b) && a != b {\n    g.addEdge(a, b)\n}","handlingStrategy":"validation","validationCode":"if !hasVertex(g, vet1) || !hasVertex(g, vet2) || vet1 == vet2 {\n    return errors.New(\"endpoints missing or self-loop\")\n}\ng.addEdge(vet1, vet2)","typeGuard":"func hasVertex(g *graphAdjList, v Vertex) bool {\n    _, ok := g.adjList[v]\n    return ok\n}","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        // skip the offending edge and continue ingesting the rest\n    }\n}()\ng.addEdge(vet1, vet2)","preventionTips":["Always addVertex for both endpoints before addEdge.","Sanitize imported edge lists: drop self-loops and unknown vertices.","Wrap bulk ingestion in recover so one bad record doesn't abort the batch."],"tags":["go","graph","adjacency-list","panic","teaching-example"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}