Skip to content

Commit 6799f00

Browse files
committed
Fixup errors, add comment
1 parent 022531e commit 6799f00

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

src/Control/Monad/Aff.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ exports._forkAff = function (nonCanceler, aff) {
8181
exports._forkAll = function (nonCanceler, foldl, affs) {
8282
var voidF = function () {};
8383

84-
return function (success, error) {
84+
return function (success) {
8585
var cancelers = foldl(function (acc) {
8686
return function (aff) {
8787
acc.push(aff(voidF, voidF));
@@ -143,7 +143,7 @@ exports._makeAff = function (cb) {
143143
};
144144

145145
exports._pure = function (nonCanceler, v) {
146-
return function (success, error) {
146+
return function (success) {
147147
success(v);
148148
return nonCanceler;
149149
};
@@ -210,7 +210,7 @@ exports._bind = function (alwaysCanceler, aff, f) {
210210
};
211211

212212
exports._attempt = function (Left, Right, aff) {
213-
return function (success, error) {
213+
return function (success) {
214214
return aff(function (v) {
215215
success(Right(v));
216216
}, function (e) {
@@ -220,36 +220,44 @@ exports._attempt = function (Left, Right, aff) {
220220
};
221221

222222
exports._runAff = function (errorT, successT, aff) {
223+
// If errorT or successT throw, and an Aff is comprised only of synchronous
224+
// effects, then it's possible for makeAff/liftEff to accidentally catch
225+
// it, which may end up rerunning the Aff depending on error recovery
226+
// behavior. To mitigate this, we observe synchronicity using mutation. If
227+
// an Aff is observed to be synchronous, we let the stack reset and run the
228+
// handlers outside of the normal callback flow.
223229
return function () {
224-
var res;
225-
var success;
226230
var status = 0;
231+
var result, success;
232+
227233
var canceler = aff(function (v) {
228234
if (status === 2) {
229235
successT(v)();
230236
} else {
231237
status = 1;
238+
result = v;
232239
success = true;
233-
res = v;
234240
}
235241
}, function (e) {
236242
if (status === 2) {
237243
errorT(e)();
238244
} else {
239245
status = 1;
246+
result = e;
240247
success = false;
241-
res = e;
242248
}
243249
});
250+
244251
if (status === 1) {
245252
if (success) {
246-
successT(res)();
253+
successT(result)();
247254
} else {
248-
errorT(res)();
255+
errorT(result)();
249256
}
250257
} else {
251258
status = 2;
252259
}
260+
253261
return canceler;
254262
};
255263
};

src/Control/Monad/Aff/Internal.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use strict";
22

33
exports._makeVar = function (nonCanceler) {
4-
return function (success, error) {
4+
return function (success) {
55
success({
66
consumers: [],
77
producers: [],
@@ -61,7 +61,7 @@ exports._putVar = function (nonCanceler, avar, a) {
6161
}
6262

6363
if (shouldQueue) {
64-
avar.producers.push(function (success, error) {
64+
avar.producers.push(function (success) {
6565
success(a);
6666
return nonCanceler;
6767
});
@@ -78,7 +78,6 @@ exports._putVar = function (nonCanceler, avar, a) {
7878
};
7979
};
8080

81-
8281
exports._killVar = function (nonCanceler, avar, e) {
8382
return function (success, error) {
8483
if (avar.error !== undefined) {

0 commit comments

Comments
 (0)