fix: sanitize API error text display and add time_blockers tests

Add extractErrorMessage helper for JSON error body parsing and apply sanitizeText across all toast displays. Add time_blockers test coverage for new holiday placeholder cleanup and overlapping scenarios.
This commit is contained in:
2026-08-22 00:34:48 +01:00
parent 388ac5948a
commit 3eec71a56c
30 changed files with 283 additions and 71 deletions
+10 -10
View File
@@ -4,7 +4,7 @@
import { SvelteDate } from 'svelte/reactivity';
import { browser } from '$app/environment';
import { toast } from 'svelte-sonner';
import { sanitizeText } from '$lib/utils/toast-safe';
import { extractErrorMessage, sanitizeText } from '$lib/utils/toast-safe';
import { apiFetch } from '$lib/utils/api';
import UserBookingModal from '$lib/components/account/UserBookingModal.svelte';
import { isValidUKPhone, formatPhoneDisplay, toE164UK } from '$lib/utils/phone';
@@ -291,7 +291,7 @@
await fetchGiftCardBalance();
} else {
const errText = await res.text();
toast.error(errText || 'Failed to redeem gift card');
toast.error(extractErrorMessage(errText) || 'Failed to redeem gift card');
}
} catch (err) {
console.error('redeemGiftCard error:', err);
@@ -357,7 +357,7 @@
}
} else {
const errText = await res.text();
toast.error(errText || 'Failed to purchase gift card');
toast.error(extractErrorMessage(errText) || 'Failed to purchase gift card');
}
} catch (err) {
console.error('buyGiftCard error:', err);
@@ -576,7 +576,7 @@
savedCardsStore.invalidate();
} else {
const errText = await res.text();
toast.error(errText || 'Failed to add card');
toast.error(extractErrorMessage(errText) || 'Failed to add card');
}
} catch (err) {
console.error('addCard error:', err);
@@ -764,7 +764,7 @@
await fetchUserData();
} else {
const text = await response.text();
toast.error(sanitizeText(text) || 'Failed to update phone number', { id: loadingToast });
toast.error(sanitizeText(extractErrorMessage(text)) || 'Failed to update phone number', { id: loadingToast });
}
} catch (err) {
console.error('Error updating phone:', err);
@@ -869,7 +869,7 @@
await fetchUserData();
} else {
const text = await response.text();
toast.error(sanitizeText(text) || 'Failed to update name', { id: loadingToast });
toast.error(sanitizeText(extractErrorMessage(text)) || 'Failed to update name', { id: loadingToast });
}
} catch (err) {
console.error('Error updating name:', err);
@@ -995,7 +995,7 @@
if (!response.ok) {
const text = await response.text();
toast.error('Failed to load upcoming bookings: ' + sanitizeText(text));
toast.error('Failed to load upcoming bookings: ' + sanitizeText(extractErrorMessage(text)));
return;
}
@@ -1034,7 +1034,7 @@
if (!response.ok) {
const text = await response.text();
toast.error('Failed to load past bookings: ' + sanitizeText(text));
toast.error('Failed to load past bookings: ' + sanitizeText(extractErrorMessage(text)));
return;
}
@@ -1155,7 +1155,7 @@
passwordData = { current: '', new: '', confirm: '' };
} else {
const text = await response.text();
toast.error(sanitizeText(text) || 'Failed to change password', { id: loadingToast });
toast.error(sanitizeText(extractErrorMessage(text)) || 'Failed to change password', { id: loadingToast });
}
} catch (err) {
console.error('Error changing password:', err);
@@ -1201,7 +1201,7 @@
goto('/');
} else {
const text = await response.text();
toast.error(sanitizeText(text) || 'Failed to delete account', { id: loadingToast });
toast.error(sanitizeText(extractErrorMessage(text)) || 'Failed to delete account', { id: loadingToast });
}
} catch (err) {
console.error('Error deleting account:', err);