concurrent.futures - Scala Futures: Default error handler for every new created, or mapped exception -


is there possibility create future{...} block default onfailure handler? (e.g. write stacktrace console)? handler should automatically attached mapped futures (new futures created calling map on future having default failure handler)

see question here more details: scala on android scala.concurrent.future not report exception on system err/out

i want have "last resort" exception logging code, if not use onfailure or sth similar on returned future.

i had similar problem, futures failing silently in cases actual result irrelevant , not handled explicitly. documentation in executioncontext assumed reportfailure method there reporting failure in future. wrong - approach came have logged exceptions (even mapped or otherwise derived) futures:

  • a loggedfuture class delegates future , onfailure logs exception similar @limbsoups answer
  • for methods map return new future yield loggedfuture well
  • use promise kind of fail event shared between cascaded loggedfutures log exception once if onfailure callback applied multiple times because of propagation
object loggedfuture {   def apply[t](future: future[t])(implicit ec: executioncontext): future[t] = {     if (future.isinstanceof[loggedfuture[t]]) {       // don't augment prevent double logging       future.asinstanceof[loggedfuture[t]]     }     else {       val failevent = promise[unit]       failevent.future.onfailure {         // actual logging here         case t => t.printstacktrace()       }       new loggedfuture(future, failevent, ec)     }   } }  private class loggedfuture[t](future: future[t], failevent: promise[unit], ec: executioncontext) extends future[t] {    // fire "log event" on failure   future.onfailure {     // complete log event promise     // promise used log error once, if     // future mapped , further callbacks attached     case t => failevent.trycomplete(failure(t))   } (ec)    // delegate methods   override def ready(atmost: duration)(implicit permit: canawait): this.type = {     future.ready(atmost)       }   override def result(atmost: scala.concurrent.duration.duration)(implicit permit: canawait): t = future.result(atmost)   override def iscompleted: boolean = future.iscompleted   override def oncomplete[u](func: scala.util.try[t] => u)(implicit executor: executioncontext): unit = future.oncomplete(func)   override def value: option[try[t]] = future.value    // propagate loggedfuture (and shared log event) whenever new future returned   override def map[s](f: t => s)(implicit executor: executioncontext): future[s] =     new loggedfuture(super.map(f), failevent, executor)   override def transform[s](s: t => s, f: throwable => throwable)(implicit executor: executioncontext): future[s] =     new loggedfuture(super.transform(s, f), failevent, executor)   override def flatmap[s](f: t => future[s])(implicit executor: executioncontext): future[s] =     new loggedfuture(super.flatmap(f), failevent, executor)   override def recover[u >: t](pf: partialfunction[throwable, u])(implicit executor: executioncontext): future[u] =     new loggedfuture(super.recover(pf), failevent, executor)   override def recoverwith[u >: t](pf: partialfunction[throwable, future[u]])(implicit executor: executioncontext): future[u] =     new loggedfuture(super.recoverwith(pf), failevent, executor)   override def zip[u](that: future[u]): future[(t, u)] =     new loggedfuture(super.zip(that), failevent, ec)   override def fallbackto[u >: t](that: future[u]): future[u] =      new loggedfuture(super.fallbackto(that), failevent, ec)   override def andthen[u](pf: partialfunction[try[t], u])(implicit executor: executioncontext): future[t] =      new loggedfuture(super.andthen(pf), failevent, executor)  }  class richfuture[t](future: future[t]) {   def aslogged(implicit ec: executioncontext): future[t] = loggedfuture(future) } 

additionally, have implicit conversion richfuture (as above) defined can convert existing futures calls future.aslogged.


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -