@@ -49,4 +49,64 @@ describe('action bridge', () => {
4949 expect ( call ) . not . toHaveBeenCalled ( )
5050 expect ( bridge . error . value ?. action ) . toBe ( 'doThing' )
5151 } )
52+
53+ it ( 'clears an action error when retrying and keeps it clear after success' , async ( ) => {
54+ expect . assertions ( 6 )
55+ const retry = Promise . withResolvers < string > ( )
56+ const call = vi . fn ( async ( ) => 'ok' )
57+ . mockRejectedValueOnce ( new Error ( 'first attempt failed' ) )
58+ . mockReturnValueOnce ( retry . promise )
59+ const bridge = createActionBridge ( { call } )
60+
61+ await expect ( bridge . handlers . refreshData ( ) ) . rejects . toThrow ( 'first attempt failed' )
62+ const pending = bridge . handlers . refreshData ( )
63+ expect ( bridge . loading . refreshData ) . toBe ( true )
64+ expect ( bridge . error . value ) . toBeNull ( )
65+ retry . resolve ( 'ok' )
66+ await expect ( pending ) . resolves . toBe ( 'ok' )
67+ expect ( bridge . error . value ) . toBeNull ( )
68+ expect ( bridge . loading . refreshData ) . toBe ( false )
69+ } )
70+
71+ it ( 'reports the new error when a retry fails' , async ( ) => {
72+ expect . assertions ( 3 )
73+ const retryError = new Error ( 'retry failed' )
74+ const call = vi . fn ( )
75+ . mockRejectedValueOnce ( new Error ( 'first attempt failed' ) )
76+ . mockRejectedValueOnce ( retryError )
77+ const bridge = createActionBridge ( { call } )
78+
79+ await expect ( bridge . handlers . refreshData ( ) ) . rejects . toThrow ( 'first attempt failed' )
80+ await expect ( bridge . handlers . refreshData ( ) ) . rejects . toThrow ( 'retry failed' )
81+ expect ( bridge . error . value ) . toEqual ( { action : 'refreshData' , error : retryError } )
82+ } )
83+
84+ it ( 'preserves an error when another action succeeds' , async ( ) => {
85+ expect . assertions ( 3 )
86+ const error = new Error ( 'refresh failed' )
87+ const call = vi . fn ( async ( ) => 'ok' ) . mockRejectedValueOnce ( error )
88+ const bridge = createActionBridge ( { call } )
89+
90+ await expect ( bridge . handlers . refreshData ( ) ) . rejects . toThrow ( 'refresh failed' )
91+ await expect ( bridge . handlers . saveData ( ) ) . resolves . toBe ( 'ok' )
92+ expect ( bridge . error . value ) . toEqual ( { action : 'refreshData' , error } )
93+ } )
94+
95+ it ( 'preserves a failure received while a retry is pending' , async ( ) => {
96+ expect . assertions ( 4 )
97+ const retry = Promise . withResolvers < string > ( )
98+ const error = new Error ( 'save failed' )
99+ const call = vi . fn ( async ( ) => 'ok' )
100+ . mockRejectedValueOnce ( new Error ( 'refresh failed' ) )
101+ . mockReturnValueOnce ( retry . promise )
102+ . mockRejectedValueOnce ( error )
103+ const bridge = createActionBridge ( { call } )
104+
105+ await expect ( bridge . handlers . refreshData ( ) ) . rejects . toThrow ( 'refresh failed' )
106+ const pending = bridge . handlers . refreshData ( )
107+ await expect ( bridge . handlers . saveData ( ) ) . rejects . toThrow ( 'save failed' )
108+ retry . resolve ( 'ok' )
109+ await expect ( pending ) . resolves . toBe ( 'ok' )
110+ expect ( bridge . error . value ) . toEqual ( { action : 'saveData' , error } )
111+ } )
52112} )
0 commit comments