Логирование ошибок хранилища

Idb-keyval — это простая обёртка над IndexedDB, предоставляющая асинхронный интерфейс для хранения ключ-значение. Основные методы включают get, set, del, clear, keys, update. Они возвращают промисы, что позволяет использовать их совместно с async/await или методами .then()/.catch().

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

await set('user', { name: 'Alex', age: 30 });
const user = await get('user');

Все операции с базой данных могут приводить к ошибкам, связанным с ограничениями браузера, переполнением хранилища или некорректными типами данных.


Стратегии логирования ошибок

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

try {
    await set('config', { theme: 'dark' });
} catch (err) {
    console.error('Ошибка записи в IndexedDB:', err);
}

Важно логировать не только сообщение ошибки, но и контекст операции: ключ, значение, тип действия (set, get, del). Это облегчает диагностику при масштабных приложениях.


2. Создание централизованного логгера ошибок

Для крупных проектов имеет смысл создать отдельную функцию для логирования, чтобы стандартизировать сообщения и хранить дополнительные метаданные.

function logDbError(action, key, value, error) {
    const logEntry = {
        timestamp: new Date().toISOString(),
        action,
        key,
        value,
        message: error.message,
        stack: error.stack
    };
    console.error('Ошибка IndexedDB:', logEntry);
}

Применение:

try {
    await set('session', { token: 'abc123' });
} catch (err) {
    logDbError('set', 'session', { token: 'abc123' }, err);
}

Такой подход позволяет интегрировать ошибки с внешними системами логирования или мониторинга.


Использование catch на уровне промиса

Idb-keyval возвращает промисы, что позволяет использовать цепочки .catch() без try/catch.

set('theme', 'light')
    .catch(err => logDbError('set', 'theme', 'light', err));

Преимущество: компактность записи и возможность обработки множества операций в функциональном стиле.


Логирование ошибок при обновлениях

Метод upd ate(key, updater) выполняет функцию обновления значения. Ошибки могут возникнуть как внутри самой функции обновления, так и при сохранении результата.

import { upd ate } from 'idb-keyval';

await upd ate('counter', oldValue => {
    if (typeof oldValue !== 'number') throw new Error('Неверный тип данных');
    return oldValue + 1;
}).catch(err => logDbError('upd ate', 'counter', null, err));

Важно фиксировать как исходное значение, так и результат функции, чтобы точно понимать, на каком шаге произошла ошибка.


Ведение истории ошибок

Для комплексного анализа часто создают отдельное хранилище для логов ошибок:

import { get, se t } from 'idb-keyval';

async function saveErrorLog(logEntry) {
    const logs = (await get('errorLogs')) || [];
    logs.push(logEntry);
    await se t('errorLogs', logs);
}

Это позволяет сохранять ошибки пользователя локально и анализировать их в дальнейшем. При этом важно не блокировать основные операции приложения из-за логирования.


Ключевые рекомендации по логированию

  • Всегда указывайте ключ и действие, связанное с ошибкой (get, set, del, update).
  • Логируйте полное сообщение ошибки и стек вызовов, чтобы было легче локализовать проблему.
  • Рассмотрите отдельное хранилище для ошибок при необходимости длительного анализа.
  • Используйте централизованную функцию логирования для унификации формата и легкой интеграции с внешними системами.
  • При критических ошибках можно предусматривать уведомления пользователя или автоматические отчёты, но базовые операции должны продолжать работу без падения приложения.

Пример комплексного подхода

async function safeSet(key, value) {
    try {
        await se t(key, value);
    } catch (err) {
        const logEntry = {
            timestamp: new Date().toISOString(),
            action: 'se t',
            key,
            value,
            message: err.message,
            stack: err.stack
        };
        await saveErrorLog(logEntry);
        console.error('Ошибка сохранения в IndexedDB:', logEntry);
    }
}

Такой подход объединяет централизованное логирование, хранение истории ошибок и сохранение контекста операции, что является базовым стандартом при работе с IndexedDB через Idb-keyval.