@@ -81,7 +81,7 @@ exports._forkAff = function (nonCanceler, aff) {
8181exports . _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
145145exports . _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
212212exports . _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
222222exports . _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} ;
0 commit comments