{"record":{"id":"3d797d967af12433","repo":"krahets/hello-algo","slug":"index-out-of-bounds-exception","errorCode":null,"errorMessage":"Index Out Of Bounds Exception","messagePattern":"Index Out Of Bounds Exception","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"codes/javascript/chapter_graph/graph_adjacency_matrix.js","lineNumber":52,"sourceCode":"        const n = this.size();\n        // 向顶点列表中添加新顶点的值\n        this.vertices.push(val);\n        // 在邻接矩阵中添加一行\n        const newRow = [];\n        for (let j = 0; j < n; j++) {\n            newRow.push(0);\n        }\n        this.adjMat.push(newRow);\n        // 在邻接矩阵中添加一列\n        for (const row of this.adjMat) {\n            row.push(0);\n        }\n    }\n\n    /* 删除顶点 */\n    removeVertex(index) {\n        if (index >= this.size()) {\n            throw new RangeError('Index Out Of Bounds Exception');\n        }\n        // 在顶点列表中移除索引 index 的顶点\n        this.vertices.splice(index, 1);\n\n        // 在邻接矩阵中删除索引 index 的行\n        this.adjMat.splice(index, 1);\n        // 在邻接矩阵中删除索引 index 的列\n        for (const row of this.adjMat) {\n            row.splice(index, 1);\n        }\n    }\n\n    /* 添加边 */\n    // 参数 i, j 对应 vertices 元素索引\n    addEdge(i, j) {\n        // 索引越界与相等处理\n        if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {\n            throw new RangeError('Index Out Of Bounds Exception');","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/codes/javascript/chapter_graph/graph_adjacency_matrix.js#L34-L70","documentation":"Thrown by removeVertex(index) on the adjacency-matrix graph (RangeError) when index >= this.size(), i.e. index is at or past the vertex count. It splices the vertex out of the vertices array and removes the matching row and column from adjMat. Note the guard only checks the upper bound — it does NOT check index < 0, so a negative index passes the guard and splice() treats it as offset-from-end, which is a latent bug.","triggerScenarios":"Calling removeVertex with an index equal to size; reusing an index after a prior removal shifted vertices down; passing the vertex value instead of its index; negative index (does NOT throw here but corrupts the matrix).","commonSituations":"Off-by-one in deletion loops; iterating a vertices array while removing (indices shift); confusing vertex index with vertex value; stale size captured before shrinking.","solutions":["Validate both bounds yourself: if (i >= 0 && i < g.size()) g.removeVertex(i);.","Iterate backward when removing multiple vertices by index so earlier indices stay valid.","Always pass the numeric index, not the vertex value.","Recompute size() after each removal; do not cache it."],"exampleFix":"// before\ng.removeVertex(i); // throws if i >= size\n// after\nif (i >= 0 && i < g.size()) g.removeVertex(i);","handlingStrategy":"validation","validationCode":"function safeRemoveVertex(g, i) {\n  if (i >= 0 && i < g.size()) g.removeVertex(i);\n}","typeGuard":"function isVertexIndex(g, i): i is number {\n  return typeof i === 'number' && Number.isInteger(i) && i >= 0 && i < g.size();\n}","tryCatchPattern":"try {\n  g.removeVertex(i);\n} catch (e) {\n  if (e instanceof RangeError && /Index Out Of Bounds/.test(e.message)) { /* skip */ } else throw e;\n}","preventionTips":["The built-in guard misses index < 0 — always validate both bounds yourself.","Pass the numeric index, not the vertex value.","Iterate backward when removing multiple vertices.","Recompute size() after each removal."],"tags":["graph","index-out-of-bounds","javascript","adjacency-matrix"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}