{"record":{"id":"7c46d0944637657f","repo":"krahets/hello-algo","slug":"illegal-argument-exception-7c46d0","errorCode":null,"errorMessage":"Illegal Argument Exception","messagePattern":"Illegal Argument Exception","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"codes/typescript/chapter_graph/graph_adjacency_list.ts","lineNumber":37,"sourceCode":"            this.addVertex(edge[0]);\n            this.addVertex(edge[1]);\n            this.addEdge(edge[0], edge[1]);\n        }\n    }\n\n    /* 获取顶点数量 */\n    size(): number {\n        return this.adjList.size;\n    }\n\n    /* 添加边 */\n    addEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // 添加边 vet1 - vet2\n        this.adjList.get(vet1).push(vet2);\n        this.adjList.get(vet2).push(vet1);\n    }\n\n    /* 删除边 */\n    removeEdge(vet1: Vertex, vet2: Vertex): void {\n        if (\n            !this.adjList.has(vet1) ||\n            !this.adjList.has(vet2) ||\n            vet1 === vet2 ||\n            this.adjList.get(vet1).indexOf(vet2) === -1\n        ) {\n            throw new Error('Illegal Argument Exception');\n        }\n        // 删除边 vet1 - vet2\n        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/codes/typescript/chapter_graph/graph_adjacency_list.ts#L19-L55","documentation":"Thrown by GraphAdjList.addEdge() when either endpoint vertex is not present in the adjacency map, or when both arguments are the exact same vertex reference (self-loop). The implementation is an undirected graph keyed by Vertex object identity in a Map, so vertices must be registered via addVertex (or the constructor) before they can be connected.","triggerScenarios":"Calling addEdge(v1, v2) where v1 or v2 was never added with addVertex; passing two references to the same Vertex instance (vet1 === vet2); passing a newly-constructed Vertex that is equal-by-value but not identical-by-reference to the one stored in the graph (Map uses reference equality for objects).","commonSituations":"Creating a fresh new Vertex(val) with the same value as an existing vertex and expecting it to resolve — Map.has() uses reference identity, so a value-duplicate but distinct object is treated as absent; forgetting to call addVertex before addEdge; attempting to model a self-loop in a graph that forbids them.","solutions":["Register both vertices first: graph.addVertex(v1); graph.addVertex(v2); before addEdge, or construct the graph from an edges array that does this.","Reuse the exact Vertex object references stored in the graph — never reconstruct equivalent Vertices by value.","Reject self-loops at the call site: if (v1 !== v2) graph.addEdge(v1, v2).","Keep a registry (Map<val, Vertex>) so you always retrieve the canonical vertex instance by value."],"exampleFix":"// before\nconst a = new Vertex(1); graph.addEdge(a, a); // throws: self-loop\nconst b = new Vertex(2); graph.addEdge(a, b); // throws if b not added\n// after\nconst a = new Vertex(1), b = new Vertex(2);\ngraph.addVertex(a); graph.addVertex(b);\nif (a !== b) graph.addEdge(a, b);","handlingStrategy":"validation","validationCode":"function safeAddEdge(graph, v1, v2) {\n  if (v1 === v2) return false; // no self-loops\n  if (!graph.adjList.has(v1) || !graph.adjList.has(v2)) return false;\n  graph.addEdge(v1, v2);\n  return true;\n}","typeGuard":"// Vertex identity guard: ensure the exact stored reference is used\nfunction isKnownVertex(graph, v) {\n  return graph.adjList.has(v);\n}","tryCatchPattern":"null","preventionTips":["Always register vertices via addVertex (or construct from edges) before addEdge.","Reuse the exact Vertex object references; never reconstruct equivalent vertices by value.","Maintain a val->Vertex registry to canonicalize lookups.","Reject self-loops (v1 === v2) at the call site."],"tags":["typescript","graph","illegal-argument","object-identity","validation"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}