Skip to content

Commit 1dfdd75

Browse files
committed
Catch errors in stores
1 parent 1409e29 commit 1dfdd75

File tree

6 files changed

+160
-5
lines changed

6 files changed

+160
-5
lines changed

dist/alt-browser-with-addons.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,18 @@ var AltStore = (function () {
10781078
}
10791079
if (model[LISTENERS][payload.action]) {
10801080
_this8[SET_STATE] = false;
1081-
var result = model[LISTENERS][payload.action](payload.data);
1081+
var result = false;
1082+
1083+
try {
1084+
result = model[LISTENERS][payload.action](payload.data);
1085+
} catch (e) {
1086+
if (_this8[LIFECYCLE].error) {
1087+
_this8[LIFECYCLE].error(e, payload.action.toString(), payload.data, _this8[STATE_CONTAINER]);
1088+
} else {
1089+
throw e;
1090+
}
1091+
}
1092+
10821093
if (result !== false && _this8[SET_STATE] === false) {
10831094
_this8.emitChange();
10841095
}

dist/alt-browser.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,18 @@ var AltStore = (function () {
822822
}
823823
if (model[LISTENERS][payload.action]) {
824824
_this8[SET_STATE] = false;
825-
var result = model[LISTENERS][payload.action](payload.data);
825+
var result = false;
826+
827+
try {
828+
result = model[LISTENERS][payload.action](payload.data);
829+
} catch (e) {
830+
if (_this8[LIFECYCLE].error) {
831+
_this8[LIFECYCLE].error(e, payload.action.toString(), payload.data, _this8[STATE_CONTAINER]);
832+
} else {
833+
throw e;
834+
}
835+
}
836+
826837
if (result !== false && _this8[SET_STATE] === false) {
827838
_this8.emitChange();
828839
}

dist/alt-with-runtime.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,18 @@ var AltStore = (function () {
7979
}
8080
if (model[LISTENERS][payload.action]) {
8181
_this8[SET_STATE] = false;
82-
var result = model[LISTENERS][payload.action](payload.data);
82+
var result = false;
83+
84+
try {
85+
result = model[LISTENERS][payload.action](payload.data);
86+
} catch (e) {
87+
if (_this8[LIFECYCLE].error) {
88+
_this8[LIFECYCLE].error(e, payload.action.toString(), payload.data, _this8[STATE_CONTAINER]);
89+
} else {
90+
throw e;
91+
}
92+
}
93+
8394
if (result !== false && _this8[SET_STATE] === false) {
8495
_this8.emitChange();
8596
}

dist/alt.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,18 @@ var AltStore = (function () {
9191
}
9292
if (model[LISTENERS][payload.action]) {
9393
_this8[SET_STATE] = false;
94-
var result = model[LISTENERS][payload.action](payload.data);
94+
var result = false;
95+
96+
try {
97+
result = model[LISTENERS][payload.action](payload.data);
98+
} catch (e) {
99+
if (_this8[LIFECYCLE].error) {
100+
_this8[LIFECYCLE].error(e, payload.action.toString(), payload.data, _this8[STATE_CONTAINER]);
101+
} else {
102+
throw e;
103+
}
104+
}
105+
95106
if (result !== false && _this8[SET_STATE] === false) {
96107
_this8.emitChange();
97108
}

src/alt.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,23 @@ class AltStore {
7878
}
7979
if (model[LISTENERS][payload.action]) {
8080
this[SET_STATE] = false
81-
const result = model[LISTENERS][payload.action](payload.data)
81+
let result = false
82+
83+
try {
84+
result = model[LISTENERS][payload.action](payload.data)
85+
} catch (e) {
86+
if (this[LIFECYCLE].error) {
87+
this[LIFECYCLE].error(
88+
e,
89+
payload.action.toString(),
90+
payload.data,
91+
this[STATE_CONTAINER]
92+
)
93+
} else {
94+
throw e
95+
}
96+
}
97+
8298
if (result !== false && this[SET_STATE] === false) {
8399
this.emitChange()
84100
}

test/failed-dispatch-test.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { assert } from 'chai'
2+
import Alt from '../dist/alt-with-runtime'
3+
import sinon from 'sinon'
4+
5+
export default {
6+
'catch failed dispatches': {
7+
'uncaught dispatches result in an error'() {
8+
const alt = new Alt()
9+
const actions = alt.generateActions('fire')
10+
11+
class Uncaught {
12+
constructor() {
13+
this.bindListeners({ fire: actions.FIRE })
14+
}
15+
16+
fire() {
17+
throw new Error('oops')
18+
}
19+
}
20+
21+
const uncaught = alt.createStore(Uncaught)
22+
23+
assert.throws(() => actions.fire())
24+
},
25+
26+
'errors can be caught though'() {
27+
const alt = new Alt()
28+
const actions = alt.generateActions('fire')
29+
30+
class Caught {
31+
constructor() {
32+
this.x = 0
33+
this.bindListeners({ fire: actions.FIRE })
34+
35+
this.on('error', () => {
36+
this.x = 1
37+
})
38+
}
39+
40+
fire() {
41+
throw new Error('oops')
42+
}
43+
}
44+
45+
const caught = alt.createStore(Caught)
46+
47+
const storeListener = sinon.spy()
48+
49+
caught.listen(storeListener)
50+
51+
assert(caught.getState().x === 0)
52+
assert.doesNotThrow(() => actions.fire())
53+
assert(caught.getState().x === 1)
54+
55+
assert.notOk(storeListener.calledOnce, 'the store did not emit a change')
56+
57+
caught.unlisten(storeListener)
58+
},
59+
60+
'you have to emit changes yourself'() {
61+
const alt = new Alt()
62+
const actions = alt.generateActions('fire')
63+
64+
class CaughtReturn {
65+
constructor() {
66+
this.x = 0
67+
this.bindListeners({ fire: actions.FIRE })
68+
69+
this.on('error', () => {
70+
this.x = 1
71+
this.emitChange()
72+
})
73+
}
74+
75+
fire() {
76+
throw new Error('oops')
77+
}
78+
}
79+
80+
const caughtReturn = alt.createStore(CaughtReturn)
81+
82+
const storeListener = sinon.spy()
83+
84+
caughtReturn.listen(storeListener)
85+
86+
assert(caughtReturn.getState().x === 0)
87+
assert.doesNotThrow(() => actions.fire())
88+
assert(caughtReturn.getState().x === 1)
89+
90+
assert.ok(storeListener.calledOnce)
91+
92+
caughtReturn.unlisten(storeListener)
93+
},
94+
}
95+
}

0 commit comments

Comments
 (0)