`.await` blows up with a macro exception
val dbIO = async[ConnectionIO] {
GeneralPracticeUserPermission.InviteUser.check(auth.userId, req.generalPracticeId).await
val invitedAt = GeneralPracticeUserInvitedAt.nowIO.toConnectionIO.await
/** run here causes the exception, it's nonsense, but the compiler should say that it's not awaitable.
*
* https://typelevel.org/cats/api/cats/free/Free.html#run(implicitS:cats.Comonad[S]):A
*/
val existingUser = GeneralPracticeUsers.queryIdByEmail(req.email).option.run.await
val user = existingUser match {
case Some(existingUserId) =>
val assignedAt = GeneralPracticeUserAssignedToPracticeAt.nowIO.toConnectionIO.await
val role = GeneralPracticeUserRole.Member
val row = GeneralPracticesToUser.Row(req.generalPracticeId, existingUserId, role, assignedAt)
GeneralPracticesToUser.Row.insert.toUpdate0(row).run.singleOrThrow_!.await
val (fullName, phone) = queryGeneralPracticeUserDetails(existingUserId).unique.await
GeneralPracticesListUsersResponse.ActiveUser(
existingUserId,
fullName,
phone,
role,
assignedAt,
)
case None =>
val row = GeneralPracticePendingUsers.Row(req.email, req.generalPracticeId, auth.userId, invitedAt)
GeneralPracticePendingUsers.Row.insert.toUpdate0(row).run.singleOrThrow_!.await
val (fullName, _) = queryGeneralPracticeUserDetails(auth.userId).unique.await
GeneralPracticesListUsersResponse.PendingUser(req.email, auth.userId, fullName, invitedAt)
}
GeneralPracticesInviteUserResponse(user)
}
Blows up with:
Exception occurred while executing macro expansion.
java.lang.AssertionError: NoDenotation.owner
at dotty.tools.dotc.core.SymDenotations$NoDenotation$.owner(SymDenotations.scala:2655)
at scala.quoted.runtime.impl.QuotesImpl$reflect$SymbolMethods$.owner(QuotesImpl.scala:2878)
at scala.quoted.runtime.impl.QuotesImpl$reflect$SymbolMethods$.owner(QuotesImpl.scala:2878)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.splicedName(SourceCode.scala:1466)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTree(SourceCode.scala:334)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTrees$$anonfun$1(SourceCode.scala:658)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printSeparated$3(SourceCode.scala:647)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printList(SourceCode.scala:653)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTrees(SourceCode.scala:658)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTree$$anonfun$7(SourceCode.scala:407)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTree$$anonfun$adapted$5(SourceCode.scala:408)
at scala.Function0.apply$mcV$sp(Function0.scala:42)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.inParens(SourceCode.scala:81)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTree(SourceCode.scala:408)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printQualTree(SourceCode.scala:548)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTree(SourceCode.scala:340)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTree(SourceCode.scala:282)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printSeparated$2(SourceCode.scala:635)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printStats(SourceCode.scala:641)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printFlatBlock$$anonfun$1(SourceCode.scala:603)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printFlatBlock$$anonfun$adapted$1(SourceCode.scala:604)
at scala.Function0.apply$mcV$sp(Function0.scala:42)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.indented(SourceCode.scala:75)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printFlatBlock(SourceCode.scala:604)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTree(SourceCode.scala:473)
at scala.quoted.runtime.impl.printers.SourceCode$.showTree(SourceCode.scala:10)
at scala.quoted.runtime.impl.QuotesImpl$$anon$13.show(QuotesImpl.scala:3472)
at scala.quoted.runtime.impl.QuotesImpl$$anon$13.show(QuotesImpl.scala:3471)
at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.show(QuotesImpl.scala:111)
at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.show(QuotesImpl.scala:111)
at cps.macros.common.TransformUtil$.safeShow(TransformUtil.scala:155)
at cps.macros.forest.RootTreeTransform.runRoot(RootTreeTransform.scala:139)
at cps.macros.forest.RootTreeTransform.runRoot$(RootTreeTransform.scala:13)
at cps.macros.forest.InlinedTreeTransform$Bridge$1.runRoot(InlinedTreeTransform.scala:290)
at cps.macros.forest.InlinedTreeTransform.runInlined(InlinedTreeTransform.scala:254)
at cps.macros.forest.InlinedTreeTransform.runInlined$(InlinedTreeTransform.scala:14)
at cps.macros.forest.InlinedTreeTransform$Bridge$1.runInlined(InlinedTreeTransform.scala:290)
at cps.macros.forest.InlinedTreeTransform$Bridge$1.bridge(InlinedTreeTransform.scala:300)
at cps.macros.forest.InlinedTreeTransform$.run(InlinedTreeTransform.scala:303)
at cps.macros.Async$.rootTransform(Async.scala:268)
at cps.macros.Async$.$anonfun$1(Async.scala:144)
at cps.macros.misc.WithOptExprProxy$.apply(WithOptExprProxy.scala:25)
at cps.macros.Async$.transformMonad(Async.scala:168)
at cps.macros.Async$.transformImpl(Async.scala:101)
at cps.macros.Async$.transformNotInlined$1(Async.scala:326)
at cps.macros.Async$.$anonfun$7(Async.scala:337)
at cps.macros.Async$.inInlined$1(Async.scala:307)
at cps.macros.Async$.transformContextLambdaImpl(Async.scala:337)
at cps.macros.Async$.inferAsyncArgApplyImpl(Async.scala:76)
run is nonsense code, but I stumbled on this because I accidentally called something else which didn't make sense and instead of an error pointing you to where you messed up you get a macro exception :S
Is it possible to get a self-contained reproduction?
Hi @arturaz fellow CPS-Async user here 👋
While any bugs reports are useful a feedback signal, reproducible reports are far, far more likely to lead to a bugfix.
I think at this point in this tool's adoption curve, as users, we should expect to need to put some work in. It's advanced technology with little competition in Scala ecosystem, that is not sponsored by any large org, and its creator is living in a warzone!
Looking at this issue, Ruslan just might have a flash of insight and recognize the problem💡, but chances are it needs to be investigated to understand what's happening.
I've been in your shoes, but I promise, it's not as much work as it seems to cut down app code to a repro example.
Here's an example I did: https://gist.github.com/benhutchison/32ed2238fc8514928d76683559bbd6ea
Key techniques:
- Scala CLI
usingdirectives to get the key dependencies - Stub any input data or context
- Delete all the lines and code that isn't directly relevant. There's lots irrelevant in your example AFAICT. Check the bug is still happening as you delete
- Simplify and cut away everything you can, alternating with checking the bug is still showing
Doesn't need perfect: when you reach a page of code or less, link it here 🙏