Классификация ошибок IndexedDB

Idb-keyval — это легковесная обертка над IndexedDB, которая упрощает работу с асинхронным хранением ключ–значение. Она предоставляет простой API для операций get, set, del и clear, позволяя хранить данные в браузере без необходимости разрабатывать сложную логику для работы с транзакциями и объектными хранилищами.

Пример базового использования:

import { get, set, del, clear } from 'idb-keyval';

await set('user', { name: 'Alice', age: 25 });
const user = await get('user');
await del('user');
await clear();

Классификация ошибок IndexedDB

Работа с IndexedDB через Idb-keyval подразумевает работу с асинхронными операциями, каждая из которых потенциально может завершиться ошибкой. Ошибки в IndexedDB имеют специфическую структуру и причины возникновения, которые можно классифицировать для упрощения обработки и отладки.

1. Ошибки открытия базы данных (OpenError)

Происходят на этапе инициализации соединения с IndexedDB. Основные причины:

  • Ошибка версии базы данных: попытка открыть базу с версией, меньшей или несовместимой с существующей.
  • Блокировка базы: если база открыта в другой вкладке и выполняется операция обновления структуры.
  • Недоступность IndexedDB: при работе в приватном режиме браузера или в средах с ограничениями безопасности.

Пример обработки ошибки открытия:

import { set } from 'idb-keyval';

try {
    await set('key', 'value');
} catch (err) {
    console.error('Ошибка открытия базы данных:', err);
}

2. Ошибки транзакций (TransactionError)

Все операции в IndexedDB выполняются через транзакции. Транзакция может быть прервана или не завершиться успешно. Типичные причины:

  • Ошибка при коммите: база данных отказалась применить изменения из-за конфликта данных.
  • Прерывание транзакции: ошибка в callback, превышение лимитов памяти, закрытие вкладки браузера.

Характерная особенность: если транзакция не завершилась, все изменения откатываются автоматически.

import { set } from 'idb-keyval';

try {
    await set('user', { name: 'Bob' });
} catch (err) {
    console.error('Ошибка транзакции:', err);
}

3. Ошибки типов данных (DataError)

IndexedDB строго проверяет типы данных, которые можно хранить:

  • Неподдерживаемые объекты: функции, DOM-элементы, объекты с циклическими ссылками.
  • Слишком большие данные: превышение лимитов хранения браузера (например, Safari ограничивает размер IndexedDB).
import { set } from 'idb-keyval';

try {
    const circular = {};
    circular.self = circular;
    await set('circular', circular);
} catch (err) {
    console.error('Ошибка данных:', err);
}

4. Ошибки доступа (PermissionError / SecurityError)

Возникают, когда скрипт не имеет разрешения на запись или чтение из IndexedDB:

  • Доступ к базе заблокирован политикой безопасности (CSP, sandbox).
  • Попытка работы из приватного режима, где IndexedDB может быть отключен.
  • Ограничения кросс-доменных запросов в браузере.
import { get } from 'idb-keyval';

try {
    const data = await get('key');
} catch (err) {
    console.error('Ошибка доступа:', err);
}

5. Ошибки очистки и удаления данных (DeleteError / ClearError)

Операции del и clear также могут завершаться ошибкой, чаще всего из-за:

  • Прерывания транзакции.
  • Одновременного обращения к одной и той же записи с нескольких вкладок.
  • Ограничений браузера на асинхронное удаление больших объемов данных.
import { del, clear } from 'idb-keyval';

try {
    await del('key');
    await clear();
} catch (err) {
    console.error('Ошибка удаления/очистки:', err);
}

Практические рекомендации по обработке ошибок

  1. Оборачивать каждую асинхронную операцию в try/catch Это гарантирует, что любая ошибка будет корректно поймана, а приложение не упадет.

  2. Использовать логирование с деталями ошибки IndexedDB возвращает объекты ошибок с полями name и message, которые помогают классифицировать проблему.

  3. Разделять ошибки по типу операции Это облегчает отладку: ошибки транзакции, ошибок данных и ошибок доступа требуют разных способов решения.

  4. Проверять доступность IndexedDB перед выполнением операций:

if (!('indexedDB' in window)) {
    console.error('IndexedDB не поддерживается в этом браузере');
}
  1. Обрабатывать циклические и слишком большие объекты заранее с помощью сериализации или проверки структуры.

Взаимодействие с Idb-keyval и обработка ошибок

Idb-keyval упрощает работу с IndexedDB, но не скрывает полностью природу ошибок. Важно учитывать, что:

  • Ошибки асинхронны, они проявляются только при await или .then/.catch.
  • Нативные ошибки IndexedDB могут иметь разные коды в зависимости от браузера.
  • Idb-keyval не бросает специфические классы ошибок, а передает объекты ошибок IndexedDB напрямую, что требует внимательной классификации по полям name и message.

Эффективная обработка ошибок позволяет строить устойчивые веб-приложения, которые сохраняют данные пользователя и корректно реагируют на ограничения среды исполнения.