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 {IDBRequestAttemptError} from "./error";
|
||||
import {IDBRequestError, IDBRequestAttemptError} from "./error";
|
||||
import {reqAsPromise} from "./utils";
|
||||
import {Transaction} from "./Transaction";
|
||||
import {LogItem} from "../../../logging/LogItem.js";
|
||||
|
@ -169,6 +169,19 @@ export class Store<T> extends QueryTarget<T> {
|
|||
const request = this._idbStore.add(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 {
|
||||
// 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 {
|
||||
constructor(request: IDBRequest, message: string = "IDBRequest failed") {
|
||||
private errorEvent: Event;
|
||||
|
||||
constructor(errorEvent: Event) {
|
||||
const request = errorEvent.target as IDBRequest;
|
||||
const source = request.source;
|
||||
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();
|
||||
});
|
||||
req.addEventListener("error", event => {
|
||||
const error = new IDBRequestError(event.target as IDBRequest<T>);
|
||||
const error = new IDBRequestError(event);
|
||||
reject(error);
|
||||
// @ts-ignore
|
||||
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> {
|
||||
// TODO: does cursor already have a value here??
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
cursorRequest.onerror = () => {
|
||||
reject(new IDBRequestError(cursorRequest));
|
||||
cursorRequest.onerror = event => {
|
||||
reject(new IDBRequestError(event));
|
||||
// @ts-ignore
|
||||
needsSyncPromise && Promise._flush && Promise._flush();
|
||||
};
|
||||
|
|
Reference in a new issue