forked from mystiq/hydrogen-web
cleanup storage errors a bit
This commit is contained in:
parent
ee4c132fb4
commit
b1f9cfd972
4 changed files with 67 additions and 40 deletions
|
@ -38,29 +38,12 @@ export const STORE_MAP = Object.freeze(STORE_NAMES.reduce((nameMap, name) => {
|
||||||
}, {}));
|
}, {}));
|
||||||
|
|
||||||
export class StorageError extends Error {
|
export class StorageError extends Error {
|
||||||
constructor(message, cause, value) {
|
constructor(message, cause) {
|
||||||
let fullMessage = message;
|
super(message);
|
||||||
if (cause) {
|
|
||||||
fullMessage += ": ";
|
|
||||||
if (typeof cause.name === "string") {
|
|
||||||
fullMessage += `(name: ${cause.name}) `;
|
|
||||||
}
|
|
||||||
if (typeof cause.code === "number") {
|
|
||||||
fullMessage += `(code: ${cause.code}) `;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value) {
|
|
||||||
fullMessage += `(value: ${JSON.stringify(value)}) `;
|
|
||||||
}
|
|
||||||
if (cause) {
|
|
||||||
fullMessage += cause.message;
|
|
||||||
}
|
|
||||||
super(fullMessage);
|
|
||||||
if (cause) {
|
if (cause) {
|
||||||
this.errcode = cause.name;
|
this.errcode = cause.name;
|
||||||
}
|
}
|
||||||
this.cause = cause;
|
this.cause = cause;
|
||||||
this.value = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
|
|
|
@ -15,8 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {QueryTarget} from "./QueryTarget.js";
|
import {QueryTarget} from "./QueryTarget.js";
|
||||||
import { reqAsPromise } from "./utils.js";
|
import {IDBRequestAttemptError} from "./utils.js";
|
||||||
import { StorageError } from "../common.js";
|
|
||||||
|
|
||||||
class QueryTargetWrapper {
|
class QueryTargetWrapper {
|
||||||
constructor(qt) {
|
constructor(qt) {
|
||||||
|
@ -43,7 +42,7 @@ class QueryTargetWrapper {
|
||||||
try {
|
try {
|
||||||
return this._qt.openKeyCursor(...params);
|
return this._qt.openKeyCursor(...params);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("openKeyCursor failed", err);
|
throw new IDBRequestAttemptError("openKeyCursor", this._qt, err, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +50,7 @@ class QueryTargetWrapper {
|
||||||
try {
|
try {
|
||||||
return this._qt.openCursor(...params);
|
return this._qt.openCursor(...params);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("openCursor failed", err);
|
throw new IDBRequestAttemptError("openCursor", this._qt, err, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ class QueryTargetWrapper {
|
||||||
try {
|
try {
|
||||||
return this._qt.put(...params);
|
return this._qt.put(...params);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("put failed", err);
|
throw new IDBRequestAttemptError("put", this._qt, err, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ class QueryTargetWrapper {
|
||||||
try {
|
try {
|
||||||
return this._qt.add(...params);
|
return this._qt.add(...params);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("add failed", err);
|
throw new IDBRequestAttemptError("add", this._qt, err, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +74,7 @@ class QueryTargetWrapper {
|
||||||
try {
|
try {
|
||||||
return this._qt.get(...params);
|
return this._qt.get(...params);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("get failed", err);
|
throw new IDBRequestAttemptError("get", this._qt, err, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +82,7 @@ class QueryTargetWrapper {
|
||||||
try {
|
try {
|
||||||
return this._qt.getKey(...params);
|
return this._qt.getKey(...params);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("getKey failed", err);
|
throw new IDBRequestAttemptError("getKey", this._qt, err, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +90,7 @@ class QueryTargetWrapper {
|
||||||
try {
|
try {
|
||||||
return this._qt.delete(...params);
|
return this._qt.delete(...params);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("delete failed", err);
|
throw new IDBRequestAttemptError("delete", this._qt, err, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +98,7 @@ class QueryTargetWrapper {
|
||||||
try {
|
try {
|
||||||
return this._qt.index(...params);
|
return this._qt.index(...params);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("index failed", err);
|
throw new IDBRequestAttemptError("index", this._qt, err, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
55
src/matrix/storage/idb/error.js
Normal file
55
src/matrix/storage/idb/error.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { StorageError } from "../common.js";
|
||||||
|
|
||||||
|
export class IDBError extends StorageError {
|
||||||
|
constructor(message, source, cause) {
|
||||||
|
const storeName = source?.name || "<unknown store>";
|
||||||
|
const databaseName = source?.transaction?.db?.name || "<unknown db>";
|
||||||
|
let fullMessage = `${message} on ${databaseName}.${storeName}`;
|
||||||
|
if (cause) {
|
||||||
|
fullMessage += ": ";
|
||||||
|
if (typeof cause.name === "string") {
|
||||||
|
fullMessage += `(name: ${cause.name}) `;
|
||||||
|
}
|
||||||
|
if (typeof cause.code === "number") {
|
||||||
|
fullMessage += `(code: ${cause.code}) `;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cause) {
|
||||||
|
fullMessage += cause.message;
|
||||||
|
}
|
||||||
|
super(fullMessage, cause);
|
||||||
|
this.storeName = storeName;
|
||||||
|
this.databaseName = databaseName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IDBRequestError extends IDBError {
|
||||||
|
constructor(request) {
|
||||||
|
const source = request?.source;
|
||||||
|
const cause = request.error;
|
||||||
|
super(`IDBRequest failed`, source, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IDBRequestAttemptError extends IDBError {
|
||||||
|
constructor(method, source, cause, params) {
|
||||||
|
super(`${method}(${params.map(p => JSON.stringify(p)).join(", ")}) failed`, source, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { IDBRequestError } from "./error.js";
|
||||||
import { StorageError } from "../common.js";
|
import { StorageError } from "../common.js";
|
||||||
|
|
||||||
let needsSyncPromise = false;
|
let needsSyncPromise = false;
|
||||||
|
@ -47,17 +48,6 @@ export async function checkNeedsSyncPromise() {
|
||||||
return needsSyncPromise;
|
return needsSyncPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
class IDBRequestError extends StorageError {
|
|
||||||
constructor(request) {
|
|
||||||
const source = request?.source;
|
|
||||||
const storeName = source?.name || "<unknown store>";
|
|
||||||
const databaseName = source?.transaction?.db?.name || "<unknown db>";
|
|
||||||
super(`Failed IDBRequest on ${databaseName}.${storeName}`, request.error);
|
|
||||||
this.storeName = storeName;
|
|
||||||
this.databaseName = databaseName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// storage keys are defined to be unsigned 32bit numbers in WebPlatform.js, which is assumed by idb
|
// storage keys are defined to be unsigned 32bit numbers in WebPlatform.js, which is assumed by idb
|
||||||
export function encodeUint32(n) {
|
export function encodeUint32(n) {
|
||||||
const hex = n.toString(16);
|
const hex = n.toString(16);
|
||||||
|
|
Loading…
Reference in a new issue