add Store.tryAdd, which prevent abort on ConstraintError
This commit is contained in:
parent
0d486a14f6
commit
12add19c31
3 changed files with 27 additions and 6 deletions
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {QueryTarget, IDBQuery} from "./QueryTarget";
|
import {QueryTarget, IDBQuery} from "./QueryTarget";
|
||||||
import {IDBRequestAttemptError} from "./error";
|
import {IDBRequestError, IDBRequestAttemptError} from "./error";
|
||||||
import {reqAsPromise} from "./utils";
|
import {reqAsPromise} from "./utils";
|
||||||
import {Transaction} from "./Transaction";
|
import {Transaction} from "./Transaction";
|
||||||
import {LogItem} from "../../../logging/LogItem.js";
|
import {LogItem} from "../../../logging/LogItem.js";
|
||||||
|
@ -169,6 +169,19 @@ export class Store<T> extends QueryTarget<T> {
|
||||||
const request = this._idbStore.add(value);
|
const request = this._idbStore.add(value);
|
||||||
this._prepareErrorLog(request, log, "add", undefined, value);
|
this._prepareErrorLog(request, log, "add", undefined, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async tryAdd(value: T, log: LogItem): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await reqAsPromise(this._idbStore.add(value));
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof IDBRequestError) {
|
||||||
|
log.log({l: "could not write", id: this._getKey(value), e: err}, log.level.Warn);
|
||||||
|
err.preventTransactionAbort();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete(keyOrKeyRange: IDBValidKey | IDBKeyRange, log?: LogItem): void {
|
delete(keyOrKeyRange: IDBValidKey | IDBKeyRange, log?: LogItem): void {
|
||||||
// ok to not monitor result of request, see comment in `put`.
|
// ok to not monitor result of request, see comment in `put`.
|
||||||
|
|
|
@ -57,10 +57,18 @@ export class IDBError extends StorageError {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class IDBRequestError extends IDBError {
|
export class IDBRequestError extends IDBError {
|
||||||
constructor(request: IDBRequest, message: string = "IDBRequest failed") {
|
private errorEvent: Event;
|
||||||
|
|
||||||
|
constructor(errorEvent: Event) {
|
||||||
|
const request = errorEvent.target as IDBRequest;
|
||||||
const source = request.source;
|
const source = request.source;
|
||||||
const cause = request.error;
|
const cause = request.error;
|
||||||
super(message, source, cause);
|
super("IDBRequest failed", source, cause);
|
||||||
|
this.errorEvent = errorEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
preventTransactionAbort() {
|
||||||
|
this.errorEvent.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ export function reqAsPromise<T>(req: IDBRequest<T>): Promise<T> {
|
||||||
needsSyncPromise && Promise._flush && Promise._flush();
|
needsSyncPromise && Promise._flush && Promise._flush();
|
||||||
});
|
});
|
||||||
req.addEventListener("error", event => {
|
req.addEventListener("error", event => {
|
||||||
const error = new IDBRequestError(event.target as IDBRequest<T>);
|
const error = new IDBRequestError(event);
|
||||||
reject(error);
|
reject(error);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
needsSyncPromise && Promise._flush && Promise._flush();
|
needsSyncPromise && Promise._flush && Promise._flush();
|
||||||
|
@ -143,8 +143,8 @@ type CursorIterator<T, I extends IDBCursor> = (value: I extends IDBCursorWithVal
|
||||||
export function iterateCursor<T, I extends IDBCursor = IDBCursorWithValue>(cursorRequest: IDBRequest<I | null>, processValue: CursorIterator<T, I>): Promise<boolean> {
|
export function iterateCursor<T, I extends IDBCursor = IDBCursorWithValue>(cursorRequest: IDBRequest<I | null>, processValue: CursorIterator<T, I>): Promise<boolean> {
|
||||||
// TODO: does cursor already have a value here??
|
// TODO: does cursor already have a value here??
|
||||||
return new Promise<boolean>((resolve, reject) => {
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
cursorRequest.onerror = () => {
|
cursorRequest.onerror = event => {
|
||||||
reject(new IDBRequestError(cursorRequest));
|
reject(new IDBRequestError(event));
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
needsSyncPromise && Promise._flush && Promise._flush();
|
needsSyncPromise && Promise._flush && Promise._flush();
|
||||||
};
|
};
|
||||||
|
|
Reference in a new issue