idb-keyval — это лёгкая обёртка над IndexedDB,
предназначенная для удобного хранения ключ-значение в браузере. Несмотря
на простоту API, важно понимать, что работа с IndexedDB всегда сопряжена
с возможными ошибками: переполнение квоты, закрытие базы данных
браузером, блокировка транзакций, ошибки сериализации объектов и др.
Библиотека предоставляет стандартные методы (get,
set, del, clear,
keys), каждый из которых возвращает
Promise, что облегчает работу с асинхронной обработкой
ошибок через .catch() или try…catch с
async/await.
Метод set(key, value) используется для записи данных в
IndexedDB. Возможные источники ошибок:
Blob;
функции и циклические структуры вызовут ошибку сериализации.Пример с обработкой ошибок:
import { set } from 'idb-keyval';
async function saveData(key, value) {
try {
await set(key, value);
console.log('Данные успешно сохранены');
} catch (error) {
console.error('Ошибка при записи данных:', error);
}
}
Важный момент: error может быть объектом
DOMException, содержащим код ошибки
(QuotaExceededError, AbortError и др.), что
позволяет точечно реагировать на разные типы проблем.
Метод get(key) возвращает значение по ключу. Ошибки
чтения могут возникать при:
undefined, что не считается ошибкой.Пример обработки чтения:
import { get } from 'idb-keyval';
async function loadData(key) {
try {
const value = await get(key);
if (value === undefined) {
console.warn('Данные по ключу не найдены');
} else {
console.log('Значение:', value);
}
} catch (error) {
console.error('Ошибка при чтении данных:', error);
}
}
Методы del(key) и clear() также возвращают
промисы. Возможные ошибки:
AbortError) — если
операция не может быть выполнена из-за конфликта с другими
транзакциями.Пример с точной обработкой:
import { del, clear } from 'idb-keyval';
async function removeData(key) {
try {
await del(key);
console.log('Ключ удалён');
} catch (error) {
console.error('Ошибка при удалении ключа:', error);
}
}
async function clearStore() {
try {
await clear();
console.log('Хранилище очищено');
} catch (error) {
console.error('Ошибка при очистке хранилища:', error);
}
}
Для надёжных приложений необходимо тестировать сценарии ошибок:
try {
const largeData = new Array(1e8).fill('x');
await set('big', largeData);
} catch (error) {
console.log(error.name); // QuotaExceededError
}
try {
await set('func', () => {});
} catch (error) {
console.log(error.message); // DataCloneError
}
abort() одной из них.Реальные приложения должны:
Пример с пользовательской реакцией:
async function saveWithRetry(key, value) {
try {
await set(key, value);
} catch (error) {
console.error('Ошибка при сохранении:', error);
// Повторная попытка через 2 секунды
setTimeout(() => saveWithRetry(key, value), 2000);
}
}
Чтобы минимизировать ошибки, полезно проверять доступное пространство и тип данных заранее:
function isSerializable(value) {
try {
structuredClone(value);
return true;
} catch {
return false;
}
}
Использование structuredClone позволяет определить,
можно ли объект безопасно сохранить в IndexedDB, не дожидаясь исключения
при записи.