catch when indexeddb is not available fix #1462
This commit is contained in:
parent
154c0e0a4a
commit
070b350211
|
@ -3,6 +3,7 @@ import { useState, useEffect, useCallback, useRef } from 'react'
|
|||
function useIndexedDB (dbName, storeName, version = 1, indices = []) {
|
||||
const [db, setDb] = useState(null)
|
||||
const [error, setError] = useState(null)
|
||||
const [notSupported, setNotSupported] = useState(false)
|
||||
const operationQueue = useRef([])
|
||||
|
||||
const handleError = useCallback((error) => {
|
||||
|
@ -27,36 +28,47 @@ function useIndexedDB (dbName, storeName, version = 1, indices = []) {
|
|||
|
||||
useEffect(() => {
|
||||
let isMounted = true
|
||||
const request = window.indexedDB.open(dbName, version)
|
||||
let request
|
||||
try {
|
||||
if (!window.indexedDB) {
|
||||
console.log('IndexedDB is not supported')
|
||||
setNotSupported(true)
|
||||
return
|
||||
}
|
||||
|
||||
request.onerror = (event) => {
|
||||
handleError(new Error('Error opening database'))
|
||||
}
|
||||
request = window.indexedDB.open(dbName, version)
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
if (isMounted) {
|
||||
const database = event.target.result
|
||||
database.onversionchange = () => {
|
||||
database.close()
|
||||
setDb(null)
|
||||
handleError(new Error('Database is outdated, please reload the page'))
|
||||
request.onerror = (event) => {
|
||||
handleError(new Error('Error opening database'))
|
||||
}
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
if (isMounted) {
|
||||
const database = event.target.result
|
||||
database.onversionchange = () => {
|
||||
database.close()
|
||||
setDb(null)
|
||||
handleError(new Error('Database is outdated, please reload the page'))
|
||||
}
|
||||
setDb(database)
|
||||
processQueue(database)
|
||||
}
|
||||
setDb(database)
|
||||
processQueue(database)
|
||||
}
|
||||
}
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const database = event.target.result
|
||||
try {
|
||||
const store = database.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true })
|
||||
request.onupgradeneeded = (event) => {
|
||||
const database = event.target.result
|
||||
try {
|
||||
const store = database.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true })
|
||||
|
||||
indices.forEach(index => {
|
||||
store.createIndex(index.name, index.keyPath, index.options)
|
||||
})
|
||||
} catch (error) {
|
||||
handleError(new Error('Error upgrading database: ' + error.message))
|
||||
indices.forEach(index => {
|
||||
store.createIndex(index.name, index.keyPath, index.options)
|
||||
})
|
||||
} catch (error) {
|
||||
handleError(new Error('Error upgrading database: ' + error.message))
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
handleError(new Error('Error opening database: ' + error.message))
|
||||
}
|
||||
|
||||
return () => {
|
||||
|
@ -68,6 +80,13 @@ function useIndexedDB (dbName, storeName, version = 1, indices = []) {
|
|||
}, [dbName, storeName, version, indices, handleError, processQueue])
|
||||
|
||||
const queueOperation = useCallback((operation) => {
|
||||
if (notSupported) {
|
||||
return Promise.reject(new Error('IndexedDB is not supported'))
|
||||
}
|
||||
if (error) {
|
||||
return Promise.reject(new Error('Database error: ' + error.message))
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const wrappedOperation = (db) => {
|
||||
try {
|
||||
|
@ -81,7 +100,7 @@ function useIndexedDB (dbName, storeName, version = 1, indices = []) {
|
|||
operationQueue.current.push(wrappedOperation)
|
||||
processQueue(db)
|
||||
})
|
||||
}, [processQueue, db])
|
||||
}, [processQueue, db, notSupported, error])
|
||||
|
||||
const add = useCallback((value) => {
|
||||
return queueOperation((db) => {
|
||||
|
@ -267,7 +286,7 @@ function useIndexedDB (dbName, storeName, version = 1, indices = []) {
|
|||
})
|
||||
}, [queueOperation, storeName])
|
||||
|
||||
return { add, get, getAll, update, remove, clear, getByIndex, getAllByIndex, getPage, error }
|
||||
return { add, get, getAll, update, remove, clear, getByIndex, getAllByIndex, getPage, error, notSupported }
|
||||
}
|
||||
|
||||
export default useIndexedDB
|
||||
|
|
|
@ -15,7 +15,7 @@ export function WalletLogs ({ wallet, embedded }) {
|
|||
const { logs, setLogs, hasMore, loadMore, loadLogs, loading } = useWalletLogs(wallet)
|
||||
useEffect(() => {
|
||||
loadLogs()
|
||||
}, [wallet])
|
||||
}, [loadLogs])
|
||||
|
||||
const showModal = useShowModal()
|
||||
|
||||
|
@ -93,22 +93,26 @@ function useWalletLogDB () {
|
|||
const { me } = useMe()
|
||||
const dbName = `app:storage${me ? `:${me.id}` : ''}`
|
||||
const idbStoreName = 'wallet_logs'
|
||||
const { add, getPage, clear, error: idbError } = useIndexedDB(dbName, idbStoreName, 1, INDICES)
|
||||
return { add, getPage, clear, error: idbError }
|
||||
const { add, getPage, clear, error, notSupported } = useIndexedDB(dbName, idbStoreName, 1, INDICES)
|
||||
return { add, getPage, clear, error, notSupported }
|
||||
}
|
||||
|
||||
export function useWalletLogger (wallet, setLogs) {
|
||||
const { add, clear } = useWalletLogDB()
|
||||
const { add, clear, notSupported } = useWalletLogDB()
|
||||
|
||||
const appendLog = useCallback(async (wallet, level, message) => {
|
||||
const log = { wallet: tag(wallet), level, message, ts: +new Date() }
|
||||
try {
|
||||
await add(log)
|
||||
if (notSupported) {
|
||||
console.log('cannot persist wallet log: indexeddb not supported')
|
||||
} else {
|
||||
await add(log)
|
||||
}
|
||||
setLogs?.(prevLogs => [log, ...prevLogs])
|
||||
} catch (error) {
|
||||
console.error('Failed to append log:', error)
|
||||
console.error('Failed to append wallet log:', error)
|
||||
}
|
||||
}, [add])
|
||||
}, [add, notSupported])
|
||||
|
||||
const [deleteServerWalletLogs] = useMutation(
|
||||
gql`
|
||||
|
@ -130,13 +134,17 @@ export function useWalletLogger (wallet, setLogs) {
|
|||
if (!wallet || wallet.sendPayment) {
|
||||
try {
|
||||
const walletTag = wallet ? tag(wallet) : null
|
||||
await clear('wallet_ts', walletTag ? window.IDBKeyRange.bound([walletTag, 0], [walletTag, Infinity]) : null)
|
||||
if (notSupported) {
|
||||
console.log('cannot clear wallet logs: indexeddb not supported')
|
||||
} else {
|
||||
await clear('wallet_ts', walletTag ? window.IDBKeyRange.bound([walletTag, 0], [walletTag, Infinity]) : null)
|
||||
}
|
||||
setLogs?.(logs => logs.filter(l => wallet ? l.wallet !== tag(wallet) : false))
|
||||
} catch (e) {
|
||||
console.error('failed to delete logs', e)
|
||||
}
|
||||
}
|
||||
}, [clear, deleteServerWalletLogs, setLogs])
|
||||
}, [clear, deleteServerWalletLogs, setLogs, notSupported])
|
||||
|
||||
const log = useCallback(level => message => {
|
||||
if (!wallet) {
|
||||
|
@ -169,20 +177,24 @@ export function useWalletLogs (wallet, initialPage = 1, logsPerPage = 10) {
|
|||
const [cursor, setCursor] = useState(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
const { getPage, error: idbError } = useWalletLogDB()
|
||||
const { getPage, error, notSupported } = useWalletLogDB()
|
||||
const [getWalletLogs] = useLazyQuery(WALLET_LOGS, SSR ? {} : { fetchPolicy: 'cache-and-network' })
|
||||
|
||||
const loadLogsPage = useCallback(async (page, pageSize, wallet) => {
|
||||
try {
|
||||
let result = { data: [], hasMore: false }
|
||||
const indexName = wallet ? 'wallet_ts' : 'ts'
|
||||
const query = wallet ? window.IDBKeyRange.bound([tag(wallet), -Infinity], [tag(wallet), Infinity]) : null
|
||||
result = await getPage(page, pageSize, indexName, query, 'prev')
|
||||
// no walletType means we're using the local IDB
|
||||
if (wallet && !wallet.walletType) {
|
||||
return result
|
||||
}
|
||||
if (notSupported) {
|
||||
console.log('cannot get client wallet logs: indexeddb not supported')
|
||||
} else {
|
||||
const indexName = wallet ? 'wallet_ts' : 'ts'
|
||||
const query = wallet ? window.IDBKeyRange.bound([tag(wallet), -Infinity], [tag(wallet), Infinity]) : null
|
||||
|
||||
result = await getPage(page, pageSize, indexName, query, 'prev')
|
||||
// no walletType means we're using the local IDB
|
||||
if (wallet && !wallet.walletType) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
const { data } = await getWalletLogs({
|
||||
variables: {
|
||||
type: wallet?.walletType,
|
||||
|
@ -207,10 +219,10 @@ export function useWalletLogs (wallet, initialPage = 1, logsPerPage = 10) {
|
|||
console.error('Error loading logs from IndexedDB:', error)
|
||||
return { data: [], total: 0, hasMore: false }
|
||||
}
|
||||
}, [getPage, setCursor, cursor])
|
||||
}, [getPage, setCursor, cursor, notSupported])
|
||||
|
||||
if (idbError) {
|
||||
console.error('IndexedDB error:', idbError)
|
||||
if (error) {
|
||||
console.error('IndexedDB error:', error)
|
||||
}
|
||||
|
||||
const loadMore = useCallback(async () => {
|
||||
|
|
Loading…
Reference in New Issue