{"record":{"id":"3a3d217dcbc48a42","repo":"krahets/hello-algo","slug":"the-deque-is-empty-3a3d21","errorCode":null,"errorMessage":"The Deque Is Empty.","messagePattern":"The Deque Is Empty\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ja/codes/javascript/chapter_stack_and_queue/array_deque.js","lineNumber":88,"sourceCode":"    /* キュー先頭からデキュー */\n    popFirst() {\n        const num = this.peekFirst();\n        // 先頭ポインタを 1 つ後ろへ進める\n        this.#front = this.index(this.#front + 1);\n        this.#queSize--;\n        return num;\n    }\n\n    /* キュー末尾からデキュー */\n    popLast() {\n        const num = this.peekLast();\n        this.#queSize--;\n        return num;\n    }\n\n    /* キュー先頭の要素にアクセス */\n    peekFirst() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.#nums[this.#front];\n    }\n\n    /* キュー末尾の要素にアクセス */\n    peekLast() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // 末尾要素のインデックスを計算\n        const last = this.index(this.#front + this.#queSize - 1);\n        return this.#nums[last];\n    }\n\n    /* 出力用の配列を返す */\n    toArray() {\n        // 有効長の範囲内のリスト要素のみを変換\n        const res = [];\n        for (let i = 0, j = this.#front; i < this.#queSize; i++, j++) {\n            res[i] = this.#nums[this.index(j)];\n        }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/ja/codes/javascript/chapter_stack_and_queue/array_deque.js#L70-L106","documentation":"Thrown by the array-based deque's peekFirst when the deque is empty. peekFirst returns the front element without removing it; the guard prevents reading #nums[#front] on a deque with queSize 0. popFirst relies on peekFirst, so it propagates the same error.","triggerScenarios":"Calling peekFirst() or popFirst() on an empty deque; reading the front after draining all elements; calling before any push.","commonSituations":"Using the deque as a BFS worklist that empties; calling peek at the start of processing before any insert; mismatched push/pop counts.","solutions":["Check deque.isEmpty() before peekFirst()/popFirst().","Structure consumers as while (!deque.isEmpty()).","Return a sentinel/null when empty instead of letting the error propagate.","Verify queSize > 0 at the call site."],"exampleFix":"// before\nconst front = deque.peekFirst();  // throws if empty\n\n// after\nconst front = deque.isEmpty() ? null : deque.peekFirst();","handlingStrategy":"validation","validationCode":"function safePeekFirst(deque) {\n  return deque.isEmpty() ? null : deque.peekFirst();\n}","typeGuard":"const isNonEmpty = (d) => typeof d.isEmpty === 'function' && !d.isEmpty();","tryCatchPattern":"try {\n  return deque.peekFirst();\n} catch (e) {\n  if (e instanceof Error && e.message === 'The Deque Is Empty.') return null;\n  throw e;\n}","preventionTips":["Check isEmpty() before peekFirst()/popFirst().","Use while (!deque.isEmpty()) for consumers.","Keep push/pop counts balanced."],"tags":["deque","javascript","empty-state","circular-array"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}