{"record":{"id":"07c3e4c2af71926f","repo":"krahets/hello-algo","slug":"error-07c3e4","errorCode":null,"errorMessage":"佇列為空","messagePattern":"佇列為空","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"zh-hant/codes/typescript/chapter_stack_and_queue/linkedlist_queue.ts","lineNumber":49,"sourceCode":"    push(num: number): void {\n        // 在尾節點後新增 num\n        const node = new ListNode(num);\n        // 如果佇列為空，則令頭、尾節點都指向該節點\n        if (!this.front) {\n            this.front = node;\n            this.rear = node;\n            // 如果佇列不為空，則將該節點新增到尾節點後\n        } else {\n            this.rear!.next = node;\n            this.rear = node;\n        }\n        this.queSize++;\n    }\n\n    /* 出列 */\n    pop(): number {\n        const num = this.peek();\n        if (!this.front) throw new Error('佇列為空');\n        // 刪除頭節點\n        this.front = this.front.next;\n        this.queSize--;\n        return num;\n    }\n\n    /* 訪問佇列首元素 */\n    peek(): number {\n        if (this.size === 0) throw new Error('佇列為空');\n        return this.front!.val;\n    }\n\n    /* 將鏈結串列轉化為 Array 並返回 */\n    toArray(): number[] {\n        let node = this.front;\n        const res = new Array<number>(this.size);\n        for (let i = 0; i < res.length; i++) {\n            res[i] = node!.val;","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/zh-hant/codes/typescript/chapter_stack_and_queue/linkedlist_queue.ts#L31-L67","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check queue.size === 0 / an isEmpty equivalent before pop.","Drain with `while (queue.size > 0)`.","Coordinate producer and consumer so pops never exceed pushes.","Return an optional from a wrapper when empty is expected."],"exampleFix":"// before: popping an empty linked-list queue throws\nconst head = queue.pop();\n\n// after: guard first\nif (queue.size > 0) {\n    const head = queue.pop();\n}","handlingStrategy":"validation","validationCode":"// Guard LinkedListQueue pop\nfunction safePop(queue: LinkedListQueue): number | undefined {\n    return queue.size > 0 ? queue.pop() : undefined;\n}\nwhile (queue.size > 0) {\n    const head = queue.pop();\n}","typeGuard":"const nonEmpty = (queue: LinkedListQueue): boolean => queue.size > 0;","tryCatchPattern":"try {\n    const head = queue.pop();\n} catch (e) {\n    if (e instanceof Error && e.message === '佇列為空') {\n        // queue empty; handle gracefully\n    } else throw e;\n}","preventionTips":["Check queue.size > 0 before pop.","Coordinate producer/consumer so pops never exceed enqueues.","Drain with `while (queue.size > 0)`.","Do not assume a prior enqueue succeeded."],"tags":["typescript","queue","linked-list","empty-collection"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}