fix(toasts): cap items array at 50 to bound runaway error toasts
Error toasts are sticky (duration: 0) so a misbehaving command that fires errors in a loop — a backend that flaps, a polling effect over a broken endpoint — accumulates toast items in the in-memory store indefinitely. The audit found no other unbounded $state arrays in the frontend stores (history caps at 500, recentNudges prunes by time, tasks/taskLists replace-on-load), but `items.push(toast)` had no upper bound. Add MAX_TOASTS = 50 with FIFO eviction. Doesn't change behaviour for realistic toast volumes; only kicks in if something is genuinely wrong. https://claude.ai/code/session_0189xUb6ie6t9qHkzatGZ9Rb
This commit is contained in:
@@ -18,6 +18,12 @@ import { errorMessage } from "$lib/utils/errors.js";
|
|||||||
|
|
||||||
let nextId = 1;
|
let nextId = 1;
|
||||||
|
|
||||||
|
// Soft cap on how many toasts can be queued at once. Error toasts are sticky
|
||||||
|
// (duration: 0) so a misbehaving command that fires errors in a loop can pile
|
||||||
|
// up indefinitely without this cap. When exceeded, the oldest toast is
|
||||||
|
// evicted to make room.
|
||||||
|
const MAX_TOASTS = 50;
|
||||||
|
|
||||||
function defaultDuration(severity: ToastSeverity): number {
|
function defaultDuration(severity: ToastSeverity): number {
|
||||||
switch (severity) {
|
switch (severity) {
|
||||||
case "success": return 3000;
|
case "success": return 3000;
|
||||||
@@ -38,6 +44,9 @@ function createToastsStore() {
|
|||||||
const duration = defaultDuration(severity);
|
const duration = defaultDuration(severity);
|
||||||
const toast = { id, severity, title, body: body ?? '', duration };
|
const toast = { id, severity, title, body: body ?? '', duration };
|
||||||
items.push(toast);
|
items.push(toast);
|
||||||
|
if (items.length > MAX_TOASTS) {
|
||||||
|
items.splice(0, items.length - MAX_TOASTS);
|
||||||
|
}
|
||||||
if (duration > 0) {
|
if (duration > 0) {
|
||||||
setTimeout(() => dismiss(id), duration);
|
setTimeout(() => dismiss(id), duration);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user