diff --git a/src/store.js b/src/store.js index b32d7b0ad..5e58855fb 100644 --- a/src/store.js +++ b/src/store.js @@ -148,7 +148,7 @@ export class Store { try { this._actionSubscribers .filter(sub => sub.after) - .forEach(sub => sub.after(action, this.state)) + .forEach(sub => sub.after(action, this.state, /* isError: */false, res)) } catch (e) { if (process.env.NODE_ENV !== 'production') { console.warn(`[vuex] error in after action subscribers: `) @@ -157,6 +157,19 @@ export class Store { } return res }) + .catch(errorResult => { + try { + this._actionSubscribers + .filter(sub => sub.after) + .forEach(sub => sub.after(action, this.state, /* isError: */true, errorResult)) + } catch (e) { + if (process.env.NODE_ENV !== 'production') { + console.warn(`[vuex] error in after action subscribers: `) + console.error(e) + } + } + throw errorResult + }) } subscribe (fn) { diff --git a/test/unit/modules.spec.js b/test/unit/modules.spec.js index a776fb582..d90af3c02 100644 --- a/test/unit/modules.spec.js +++ b/test/unit/modules.spec.js @@ -669,12 +669,12 @@ describe('Modules', () => { ) }) - it('action before/after subscribers', (done) => { + it('action before/after subscribers with resolve()', (done) => { const beforeSpy = jasmine.createSpy() const afterSpy = jasmine.createSpy() const store = new Vuex.Store({ actions: { - [TEST]: () => Promise.resolve() + [TEST]: () => Promise.resolve('resolve') }, plugins: [ store => { @@ -694,7 +694,43 @@ describe('Modules', () => { Vue.nextTick(() => { expect(afterSpy).toHaveBeenCalledWith( { type: TEST, payload: 2 }, - store.state + store.state, + false, + 'resolve' + ) + done() + }) + }) + }) + + it('action before/after subscribers with reject()', (done) => { + const beforeSpy = jasmine.createSpy() + const afterSpy = jasmine.createSpy() + const store = new Vuex.Store({ + actions: { + [TEST]: () => Promise.reject('reject') + }, + plugins: [ + store => { + store.subscribeAction({ + before: beforeSpy, + after: afterSpy + }) + } + ] + }) + store.dispatch(TEST, 2) + expect(beforeSpy).toHaveBeenCalledWith( + { type: TEST, payload: 2 }, + store.state + ) + expect(afterSpy).not.toHaveBeenCalled() + Vue.nextTick(() => { + expect(afterSpy).toHaveBeenCalledWith( + { type: TEST, payload: 2 }, + store.state, + false, + 'reject' ) done() })