{"record":{"id":"a098711e1e460e64","repo":"krahets/hello-algo","slug":"the-deque-is-empty-a09871","errorCode":null,"errorMessage":"The Deque Is Empty.","messagePattern":"The Deque Is Empty\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ru/codes/javascript/chapter_stack_and_queue/array_deque.js","lineNumber":88,"sourceCode":"    /* Извлечение из головы очереди */\n    popFirst() {\n        const num = this.peekFirst();\n        // Указатель головы сдвигается на одну позицию назад\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/ru/codes/javascript/chapter_stack_and_queue/array_deque.js#L70-L106","documentation":"Thrown by ArrayDeque.peekFirst (JS) with message 'The Deque Is Empty.' when reading the front element of an empty deque. peekFirst underlies popFirst, so the same throw propagates from popFirst on an empty deque.","triggerScenarios":"Calling peekFirst() (or popFirst(), which delegates to it) when #queSize === 0.","commonSituations":"Treating the deque as a stack/queue and popping past empty; consumer/producer imbalance where consumers drain faster than producers fill.","solutions":["Guard with isEmpty(): if (!deque.isEmpty()) deque.popFirst().","Use peekFirst() to test before consuming.","Track expected element counts on the producer side."],"exampleFix":"// before\nconst x = deque.popFirst(); // throws when empty\n\n// after\nconst x = deque.isEmpty() ? null : deque.popFirst();","handlingStrategy":"validation","validationCode":"const x = deque.isEmpty() ? null : deque.popFirst();","typeGuard":null,"tryCatchPattern":"try { deque.popFirst(); } catch (e) { if (e.message !== 'The Deque Is Empty.') throw e; }","preventionTips":["Gate every popFirst/peekFirst on isEmpty().","In producer/consumer code, backpressure on empty rather than over-popping.","Return a sentinel from a wrapper to keep call sites clean."],"tags":["deque","javascript","precondition","empty-state","hello-algo"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}