mill icon indicating copy to clipboard operation
mill copied to clipboard

Add `ResultFailureException` and `T.fail` convenience API

Open lefou opened this issue 1 year ago • 5 comments

The T.fail shortcut is an experiment. Pease comment WDYT.

This change was discussed in https://github.com/com-lihaoyi/mill/pull/3406

I'd also like to remove the Exception from Result.Failing hierarchy, but it was added before the last stable release, so this would be considered a binary incompatible change.

lefou avatar Aug 26 '24 13:08 lefou

The test covering this task:

    def sometimesFailingWithException(fail: Boolean): Task[String] = T.task {
      if (!fail) "Success"
      else T.fail("Failure")
    }

fails with

X mill.eval.SeqTaskTests.sometimeFailingWithException.failure 2ms 
  java.lang.AssertionError: assertion failed: ==> assertion failed: Left(mill.api.ResultFailureException: Failure
      mill.api.Ctx$Fail.fail(Ctx.scala:109)
      mill.api.Ctx$Fail.fail$(Ctx.scala:109)
      mill.api.Ctx.fail(Ctx.scala:124)
      mill.define.Target$.fail(Task.scala:199)
      mill.eval.TaskTests$Build.$anonfun$sometimesFailingWithException$1(TaskTests.scala:129)
      mill.define.Task$TraverseCtx.evaluate(Task.scala:71)) != Left(mill.api.Result$Failure)
    scala.Predef$.assert(Predef.scala:279)
    utest.asserts.Asserts$ArrowAssert.$eq$eq$greater(Asserts.scala:90)
    mill.eval.TaskTests.$anonfun$tests$44(TaskTests.scala:285)
    mill.eval.TaskTests.$anonfun$tests$44$adapted(TaskTests.scala:284)
    mill.eval.SeqTaskTests$.withEnv(TaskTests.scala:296)
    mill.eval.TaskTests.$anonfun$tests$43(TaskTests.scala:149)

So, I wonder why?

The T.task macro expects a Result[T], but I return a not-Result-type, so I think the compiler should apply the implicit Result.create method, which surrounds the t: => T with a try-catch-block to lift the ResultFailureException thrown by T.fail into a Result.Failure. Yet, it's obviously not working as I think it should. Any ideas?

lefou avatar Aug 28 '24 15:08 lefou

Instead of converting to a Result.Failure you could add a rule to pretty print the error message as I did in the other PR for Result.Exception(Result.Failure) but for Result.Exception(ResultFailureException) What do you think?

lolgab avatar Aug 28 '24 19:08 lolgab

Instead of converting to a Result.Failure you could add a rule to pretty print the error message as I did in the other PR for Result.Exception(Result.Failure) but for Result.Exception(ResultFailureException) What do you think?

The idea is, to keep the control flow of tasks returning results functional. I still have this idea in my mind, that we one day can recover from failed tasks (https://github.com/com-lihaoyi/mill/discussions/1779), but that's only possible if we stick to a uniform way of failing.

lefou avatar Aug 28 '24 19:08 lefou

I think this approach looks fine by me

lihaoyi avatar Sep 02 '24 01:09 lihaoyi

This PR is still in draft state, since there is one open issue: https://github.com/com-lihaoyi/mill/pull/3422#issuecomment-2315741498. Has an fix or an idea?

lefou avatar Sep 08 '24 20:09 lefou

Superseded by https://github.com/com-lihaoyi/mill/pull/4964

lefou avatar Apr 19 '25 11:04 lefou