{"record":{"id":"05b0a8add7532a7d","repo":"krahets/hello-algo","slug":"error-05b0a8","errorCode":null,"errorMessage":"佇列為空","messagePattern":"佇列為空","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"zh-hant/codes/typescript/chapter_stack_and_queue/array_queue.ts","lineNumber":58,"sourceCode":"        // 透過取餘操作實現 rear 越過陣列尾部後回到頭部\n        const rear = (this.front + this.queSize) % this.capacity;\n        // 將 num 新增至佇列尾\n        this.nums[rear] = num;\n        this.queSize++;\n    }\n\n    /* 出列 */\n    pop(): number {\n        const num = this.peek();\n        // 佇列首指標向後移動一位，若越過尾部，則返回到陣列頭部\n        this.front = (this.front + 1) % this.capacity;\n        this.queSize--;\n        return num;\n    }\n\n    /* 訪問佇列首元素 */\n    peek(): number {\n        if (this.isEmpty()) throw new Error('佇列為空');\n        return this.nums[this.front];\n    }\n\n    /* 返回 Array */\n    toArray(): number[] {\n        // 僅轉換有效長度範圍內的串列元素\n        const arr = new Array(this.size);\n        for (let i = 0, j = this.front; i < this.size; i++, j++) {\n            arr[i] = this.nums[j % this.capacity];\n        }\n        return arr;\n    }\n}\n\n/* Driver Code */\n/* 初始化佇列 */\nconst capacity = 10;\nconst queue = new ArrayQueue(capacity);","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/zh-hant/codes/typescript/chapter_stack_and_queue/array_queue.ts#L40-L76","documentation":"An Error '佇列為空' ('queue is empty') thrown by peek() in ArrayQueue (array_queue.ts:58). peek() returns nums[front]; on an empty queue front is stale, so the guard prevents returning garbage. pop() calls peek() first, so the same guard blocks popping an empty queue.","triggerScenarios":"Calling queue.peek() or queue.pop() when queue.isEmpty() is true (queSize === 0). Popping more than was pushed, or operating on a queue that was never filled after construction.","commonSituations":"Off-by-one in a consumer loop; FIFO producer/consumer where the consumer outruns the producer; assuming the queue has data because capacity > 0; mixing this ring-array queue's API with a list-based one and forgetting the explicit emptiness check.","solutions":["Check queue.isEmpty() before peek/pop.","Consume with `while (!queue.isEmpty())` or coordinate with the producer so pops never exceed pushes.","Use size() for the element count, not the backing capacity.","Return an optional/sentinel from a wrapper when empty is a normal condition."],"exampleFix":"// before: popping an empty queue throws\nconst head = queue.pop();\n\n// after: guard with emptiness check\nconst head = queue.isEmpty() ? undefined : queue.pop();","handlingStrategy":"validation","validationCode":"// Guard ArrayQueue peek/pop\nfunction safePop(queue: ArrayQueue): number | undefined {\n    return queue.isEmpty() ? undefined : queue.pop();\n}\nwhile (!queue.isEmpty()) {\n    const head = queue.pop();\n}","typeGuard":"const nonEmpty = (queue: ArrayQueue): boolean => !queue.isEmpty();","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 isEmpty() (or size() === 0) before peek/pop.","In producer/consumer code, ensure pops never exceed pushes.","Use size() for element count, not capacity().","Drain with `while (!queue.isEmpty())`."],"tags":["typescript","queue","ring-array","empty-collection"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}