{"record":{"id":"640e47887f41bc71","repo":"krahets/hello-algo","slug":"index-out-of-bounds-exception-640e47","errorCode":null,"errorMessage":"Index Out Of Bounds Exception","messagePattern":"Index Out Of Bounds Exception","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"zh-hant/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/zh-hant/codes/javascript/chapter_graph/graph_adjacency_matrix.js#L34-L70","documentation":"Thrown by GraphAdjMatrix.removeVertex(index) when index >= size(). The method splices the vertex out of both the vertices array and the adjacency matrix. Note: the guard checks only index >= size() — it does NOT check index < 0, so a negative index bypasses the guard and splice treats it as an offset-from-end, silently corrupting the matrix.","triggerScenarios":"Passing an index >= the current vertex count, or passing a negative index (which slips past the incomplete guard and corrupts data).","commonSituations":"Off-by-one after batch removals; confusing a vertex's value/label with its positional index; stale size assumption after vertices were removed; using -1 as a sentinel that bypasses the check.","solutions":["Validate 0 <= index < graph.size() before calling removeVertex.","Never pass negative indices — the built-in guard does not reject them.","If you hold a vertex value, resolve its positional index via vertices.indexOf(value) first."],"exampleFix":"// before\ngraph.removeVertex(index); // throws if index >= size()\n\n// after\nif (index >= 0 && index < graph.size()) {\n    graph.removeVertex(index);\n}","handlingStrategy":"validation","validationCode":"// Full bounds check including negative index (the built-in guard misses negatives)\nif (index >= 0 && index < graph.size()) {\n    graph.removeVertex(index);\n}","typeGuard":"function isValidVertexIndex(graph, index) {\n    return Number.isInteger(index) && index >= 0 && index < graph.size();\n}","tryCatchPattern":"try {\n    graph.removeVertex(index);\n} catch (e) {\n    if (e instanceof RangeError) {\n        // index out of bounds — handle\n    } else throw e;\n}","preventionTips":["Always check both lower (>= 0) and upper (< size) bounds — the library only checks the upper.","Use positional index, not the vertex value, for matrix-based graph APIs.","Re-resolve indices after any removeVertex shifts positions."],"tags":["graph","adjacency-matrix","javascript","index-out-of-bounds","precondition"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}