{"record":{"id":"09bfb5cdeffca5c4","repo":"krahets/hello-algo","slug":"the-deque-is-empty-09bfb5","errorCode":null,"errorMessage":"The Deque Is Empty.","messagePattern":"The Deque Is Empty\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ja/codes/typescript/chapter_stack_and_queue/array_deque.ts","lineNumber":88,"sourceCode":"    /* キュー先頭からデキュー */\n    popFirst(): number {\n        const num: number = this.peekFirst();\n        // 先頭ポインタを 1 つ後ろへ進める\n        this.front = this.index(this.front + 1);\n        this.queSize--;\n        return num;\n    }\n\n    /* キュー末尾からデキュー */\n    popLast(): number {\n        const num: number = this.peekLast();\n        this.queSize--;\n        return num;\n    }\n\n    /* キュー先頭の要素にアクセス */\n    peekFirst(): number {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.nums[this.front];\n    }\n\n    /* キュー末尾の要素にアクセス */\n    peekLast(): number {\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(): number[] {\n        // 有効長の範囲内のリスト要素のみを変換\n        const res: number[] = [];\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/typescript/chapter_stack_and_queue/array_deque.ts#L70-L106","documentation":"Thrown by peekFirst() on the array-backed deque when `isEmpty()` is true (queSize === 0). It is a plain Error guarding direct front access; peekFirst is also called internally by popFirst, so the same throw surfaces from popFirst on an empty deque.","triggerScenarios":"Calling peekFirst() (or popFirst, which delegates to peekFirst) on a deque with queSize 0; dequeuing more than was enqueued; peeking after a clear/reset without re-checking size.","commonSituations":"Processing a queue that drained faster than it filled; using peekFirst as a non-failing check (it throws, it does not return undefined); off-by-one in a producer/consumer that over-consumes one element.","solutions":["Guard with `if (!deque.isEmpty())` before peekFirst/popFirst.","Loop with `while (!deque.isEmpty())` when draining.","Wrap in try/catch if an empty deque is an expected, recoverable state."],"exampleFix":"// before\nconst head = deque.peekFirst();\n\n// after\nconst head = deque.isEmpty() ? undefined : deque.peekFirst();","handlingStrategy":"validation","validationCode":"// Guard front access on the deque.\nif (!deque.isEmpty()) {\n  const head = deque.peekFirst();\n}","typeGuard":"function dequeCanPeek(deque) {\n  return !deque.isEmpty();\n}","tryCatchPattern":"try {\n  const head = deque.peekFirst();\n} catch (e) {\n  if (e instanceof Error && /Deque Is Empty/.test(e.message)) {\n    // empty — handle gracefully\n  } else throw e;\n}","preventionTips":["Always check isEmpty() before peekFirst/popFirst (popFirst delegates to peekFirst).","Drain with `while (!deque.isEmpty())`.","Treat peekFirst as throwing, never as returning undefined on empty.","In producer/consumer code, gate consumption on size > 0."],"tags":["deque","queue","empty-state","typescript"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}