{"record":{"id":"5295481e0dbefec8","repo":"krahets/hello-algo","slug":"error-529548","errorCode":null,"errorMessage":"堆疊為空","messagePattern":"堆疊為空","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"zh-hant/codes/typescript/chapter_stack_and_queue/linkedlist_stack.ts","lineNumber":39,"sourceCode":"    }\n\n    /* 判斷堆疊是否為空 */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* 入堆疊 */\n    push(num: number): void {\n        const node = new ListNode(num);\n        node.next = this.stackPeek;\n        this.stackPeek = node;\n        this.stkSize++;\n    }\n\n    /* 出堆疊 */\n    pop(): number {\n        const num = this.peek();\n        if (!this.stackPeek) throw new Error('堆疊為空');\n        this.stackPeek = this.stackPeek.next;\n        this.stkSize--;\n        return num;\n    }\n\n    /* 訪問堆疊頂元素 */\n    peek(): number {\n        if (!this.stackPeek) throw new Error('堆疊為空');\n        return this.stackPeek.val;\n    }\n\n    /* 將鏈結串列轉化為 Array 並返回 */\n    toArray(): number[] {\n        let node = this.stackPeek;\n        const res = new Array<number>(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node!.next;","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/zh-hant/codes/typescript/chapter_stack_and_queue/linkedlist_stack.ts#L21-L57","documentation":"An Error '堆疊為空' ('stack is empty') thrown by pop() in LinkedListStack (linkedlist_stack.ts:39). pop() first calls peek() (which is guarded), then advances stackPeek to stackPeek.next; the `if (!this.stackPeek)` check blocks unlinking the head of an empty list, preventing a null dereference when reading .next on null.","triggerScenarios":"Calling stack.pop() when this.stackPeek is null (stkSize === 0). Popping more than you pushed, or popping a freshly constructed `new LinkedListStack()`.","commonSituations":"Unbalanced push/pop in expression evaluation or backtracking; popping after a previous pop emptied the stack; DFS that pops on backtrack without checking depth; reusing a stack instance across runs without resetting state.","solutions":["Check stack.isEmpty() (or stkSize === 0) before pop.","Drain with `while (!stack.isEmpty())`.","Track pushes and never pop more than that.","Return an optional from a wrapper when empty is a normal outcome."],"exampleFix":"// before: popping an empty linked-list stack throws\nconst top = stack.pop();\n\n// after: guard first\nif (!stack.isEmpty()) {\n    const top = stack.pop();\n}","handlingStrategy":"validation","validationCode":"// Guard LinkedListStack pop\nfunction safePop(stack: LinkedListStack): number | undefined {\n    return stack.isEmpty() ? undefined : stack.pop();\n}\nwhile (!stack.isEmpty()) {\n    const top = stack.pop();\n}","typeGuard":"const nonEmpty = (stack: LinkedListStack): boolean => !stack.isEmpty();","tryCatchPattern":"try {\n    const top = stack.pop();\n} catch (e) {\n    if (e instanceof Error && e.message === '堆疊為空') {\n        // stack empty; handle gracefully\n    } else throw e;\n}","preventionTips":["Check isEmpty() before pop.","Track pushes and never pop more than that.","Drain with `while (!stack.isEmpty())`.","Reset shared stack instances between runs."],"tags":["typescript","stack","linked-list","empty-collection"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}