@@ -176,11 +176,9 @@ describe('IDBKeyValProvider', () => {
176176
177177 describe ( 'write-error normalization (aborted transactions)' , ( ) => {
178178 // A write transaction aborted by something other than its own request (connection close,
179- // versionchange, a sibling transaction) leaves `transaction.error === null`. idb-keyval
180- // rejects with that null, which is unclassifiable: it slips past createStore's heal guards
181- // (they require an Error/DOMException) and renders as the production log line
182- // "[Onyx] Failed to save to storage. Error: null". Every write path must instead reject
183- // with a real Error so the failure can be classified and retried sanely.
179+ // versionchange, a sibling transaction) leaves `transaction.error === null`, which idb-keyval
180+ // rejects with as-is. Every write path must instead reject with a real Error so the failure
181+ // can be classified and retried.
184182 function abortTransactionOnPut ( ) {
185183 const originalPut = IDBObjectStore . prototype . put ;
186184 jest . spyOn ( IDBObjectStore . prototype , 'put' ) . mockImplementation ( function put ( this : IDBObjectStore , ...args : Parameters < IDBObjectStore [ 'put' ] > ) {
@@ -190,6 +188,15 @@ describe('IDBKeyValProvider', () => {
190188 } ) ;
191189 }
192190
191+ function abortTransactionOnDelete ( ) {
192+ const originalDelete = IDBObjectStore . prototype . delete ;
193+ jest . spyOn ( IDBObjectStore . prototype , 'delete' ) . mockImplementation ( function del ( this : IDBObjectStore , ...args : Parameters < IDBObjectStore [ 'delete' ] > ) {
194+ const request = originalDelete . apply ( this , args ) ;
195+ this . transaction . abort ( ) ;
196+ return request ;
197+ } ) ;
198+ }
199+
193200 function expectAbortError ( error : unknown ) {
194201 expect ( error ) . not . toBeNull ( ) ;
195202 expect ( error ) . toBeInstanceOf ( DOMException ) ;
@@ -218,6 +225,24 @@ describe('IDBKeyValProvider', () => {
218225 const error = await IDBKeyValProvider . multiMerge ( [ [ ONYXKEYS . TEST_KEY , 'value' ] ] ) . catch ( ( e : unknown ) => e ) ;
219226 expectAbortError ( error ) ;
220227 } ) ;
228+
229+ it ( 'should reject setItem(null) with a tagged AbortError, never null' , async ( ) => {
230+ abortTransactionOnDelete ( ) ;
231+ const error = await IDBKeyValProvider . setItem ( ONYXKEYS . TEST_KEY , null ) . catch ( ( e : unknown ) => e ) ;
232+ expectAbortError ( error ) ;
233+ } ) ;
234+
235+ it ( 'should reject removeItem with a tagged AbortError, never null' , async ( ) => {
236+ abortTransactionOnDelete ( ) ;
237+ const error = await IDBKeyValProvider . removeItem ( ONYXKEYS . TEST_KEY ) . catch ( ( e : unknown ) => e ) ;
238+ expectAbortError ( error ) ;
239+ } ) ;
240+
241+ it ( 'should reject removeItems with a tagged AbortError, never null' , async ( ) => {
242+ abortTransactionOnDelete ( ) ;
243+ const error = await IDBKeyValProvider . removeItems ( [ ONYXKEYS . TEST_KEY ] ) . catch ( ( e : unknown ) => e ) ;
244+ expectAbortError ( error ) ;
245+ } ) ;
221246 } ) ;
222247
223248 describe ( 'mergeItem' , ( ) => {
0 commit comments