@@ -81,7 +81,7 @@ exports._forkAff = function (nonCanceler, aff) {
81
81
exports . _forkAll = function ( nonCanceler , foldl , affs ) {
82
82
var voidF = function ( ) { } ;
83
83
84
- return function ( success , error ) {
84
+ return function ( success ) {
85
85
var cancelers = foldl ( function ( acc ) {
86
86
return function ( aff ) {
87
87
acc . push ( aff ( voidF , voidF ) ) ;
@@ -143,7 +143,7 @@ exports._makeAff = function (cb) {
143
143
} ;
144
144
145
145
exports . _pure = function ( nonCanceler , v ) {
146
- return function ( success , error ) {
146
+ return function ( success ) {
147
147
success ( v ) ;
148
148
return nonCanceler ;
149
149
} ;
@@ -210,7 +210,7 @@ exports._bind = function (alwaysCanceler, aff, f) {
210
210
} ;
211
211
212
212
exports . _attempt = function ( Left , Right , aff ) {
213
- return function ( success , error ) {
213
+ return function ( success ) {
214
214
return aff ( function ( v ) {
215
215
success ( Right ( v ) ) ;
216
216
} , function ( e ) {
@@ -220,36 +220,44 @@ exports._attempt = function (Left, Right, aff) {
220
220
} ;
221
221
222
222
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.
223
229
return function ( ) {
224
- var res ;
225
- var success ;
226
230
var status = 0 ;
231
+ var result , success ;
232
+
227
233
var canceler = aff ( function ( v ) {
228
234
if ( status === 2 ) {
229
235
successT ( v ) ( ) ;
230
236
} else {
231
237
status = 1 ;
238
+ result = v ;
232
239
success = true ;
233
- res = v ;
234
240
}
235
241
} , function ( e ) {
236
242
if ( status === 2 ) {
237
243
errorT ( e ) ( ) ;
238
244
} else {
239
245
status = 1 ;
246
+ result = e ;
240
247
success = false ;
241
- res = e ;
242
248
}
243
249
} ) ;
250
+
244
251
if ( status === 1 ) {
245
252
if ( success ) {
246
- successT ( res ) ( ) ;
253
+ successT ( result ) ( ) ;
247
254
} else {
248
- errorT ( res ) ( ) ;
255
+ errorT ( result ) ( ) ;
249
256
}
250
257
} else {
251
258
status = 2 ;
252
259
}
260
+
253
261
return canceler ;
254
262
} ;
255
263
} ;
0 commit comments