Allows logging in a tree structure so that comprehensive logging does not become incomprehensible
@channingwalton Would it make sense to have something like
```
trait LogTreeSyntax[Annotation, Error: Show] {
type LogTree = Tree[LogTreeLabel[Annotation]]
type LogTreeWriter[Value] = Writer[LogTree, Value]
type DescribedComputation[Value] = EitherT[LogTreeWriter, Error, Value]
```?
type DescribedComputation[Value]
doesn't work out
def failure[V](description: String)
to be def failure[V, Err: Show](description: Err)
yep.
Now i have ugly combination of
case class FutureDescribedComputation[A](run: Future[DescribedComputation[A]]) {
def flatMap[B](f : A => FutureDescribedComputation[B])
(implicit exec: ExecutionContext) : FutureDescribedComputation[B] =
FutureDescribedComputation(
run.flatMap { dca : DescribedComputation[A] =>
dca.run.value.fold(
s => Future.successful( EitherT.left[LogTreeWriter, String, B]( dca.run.map(_ => s) ) ),
(a : A) => f(a).run.map { x => dca.flatMap { _ => x } } )
}
)
def map[B](f : A => B)(implicit exec: ExecutionContext) : FutureDescribedComputation[B] =
FutureDescribedComputation( run.map { x => x.map { f } } )
}
and future.recover{ case t => failure("Client lookup”) ~~ t}
val rec = "test" ~< {
val dc = "compute".left[Int] ~>? (l => l, r => r.toString)
dc.handleError { x => 1 ~> "recoveried" }
}
println(rec.run.written.show)
Failed: test
Failed: compute
recoveried
test
tag success because it is recoveried from errors? thanks. nice lib by the way
@chenharryhua You could just pattern match against rec.run.value. If I do this:
import scalaz.std.string._
import treelog.LogTreeSyntaxWithoutAnnotations
import treelog.LogTreeSyntaxWithoutAnnotations._
import scalaz.syntax.plus._
import scalaz.syntax.show._
import scalaz.syntax.monadError._
val planAThatDoesntWork: LogTreeSyntaxWithoutAnnotations.DescribedComputation[Int] = failure[Int]("Oh dear....")
val backupPlan: LogTreeSyntaxWithoutAnnotations.DescribedComputation[Int] = 42 ~> "This one works"
val putThemTogether = planAThatDoesntWork <+> backupPlan
putThemTogether.run.value // Yields a value, 42.
putThemTogether.run.written.shows // Shows that there *was* a failure, and that we recover.
val anotherWay = planAThatDoesntWork.handleError(_ => backupPlan)
anotherWay.run.value
anotherWay.run.written.shows
, I see values (along with the failure in the log).
LogTreeWriter
is not WriterT
but just WriterT[Id, _]
. I think handling monadic values with treelog would be not so rare demand.