krahets/hello-algo · error · Error

佇列為空

Error message

佇列為空

What it means

An Error '佇列為空' ('queue is empty') thrown by pop() in LinkedListQueue (linkedlist_queue.ts:49). pop() first calls peek() (which has its own guard), then dereferences this.front.next; the `if (!this.front)` check is a defensive duplicate that blocks unlinking the head of an empty list. On an empty queue front is null, so the guard prevents a null-pointer dereference.

Source

Thrown at zh-hant/codes/typescript/chapter_stack_and_queue/linkedlist_queue.ts:49

    push(num: number): void {
        // 在尾節點後新增 num
        const node = new ListNode(num);
        // 如果佇列為空,則令頭、尾節點都指向該節點
        if (!this.front) {
            this.front = node;
            this.rear = node;
            // 如果佇列不為空,則將該節點新增到尾節點後
        } else {
            this.rear!.next = node;
            this.rear = node;
        }
        this.queSize++;
    }

    /* 出列 */
    pop(): number {
        const num = this.peek();
        if (!this.front) throw new Error('佇列為空');
        // 刪除頭節點
        this.front = this.front.next;
        this.queSize--;
        return num;
    }

    /* 訪問佇列首元素 */
    peek(): number {
        if (this.size === 0) throw new Error('佇列為空');
        return this.front!.val;
    }

    /* 將鏈結串列轉化為 Array 並返回 */
    toArray(): number[] {
        let node = this.front;
        const res = new Array<number>(this.size);
        for (let i = 0; i < res.length; i++) {
            res[i] = node!.val;

View on GitHub (pinned to 69932aed18)

Solutions

  1. Check queue.size === 0 / an isEmpty equivalent before pop.
  2. Drain with `while (queue.size > 0)`.
  3. Coordinate producer and consumer so pops never exceed pushes.
  4. Return an optional from a wrapper when empty is expected.

Example fix

// before: popping an empty linked-list queue throws
const head = queue.pop();

// after: guard first
if (queue.size > 0) {
    const head = queue.pop();
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard LinkedListQueue pop
function safePop(queue: LinkedListQueue): number | undefined {
    return queue.size > 0 ? queue.pop() : undefined;
}
while (queue.size > 0) {
    const head = queue.pop();
}

Type guard

const nonEmpty = (queue: LinkedListQueue): boolean => queue.size > 0;

Try / catch

try {
    const head = queue.pop();
} catch (e) {
    if (e instanceof Error && e.message === '佇列為空') {
        // queue empty; handle gracefully
    } else throw e;
}

Prevention

When it happens

Trigger: Calling queue.pop() when the queue has no nodes — i.e., this.front is null / this.size === 0. Popping more than was pushed, or popping a freshly constructed queue.

Common situations: Producer/consumer imbalance where the consumer pops faster than the producer enqueues; draining the queue in a loop without an emptiness check; reusing a queue after it was emptied; assuming a previous push left a node in place.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/07c3e4c2af71926f. Report an issue: GitHub.