mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 14:40:17 +00:00
feat(compiler): Handle error function exit in tracing mode [LNG-250] (#921)
* Wrap function calls with xor * Do not detach tracing call in case of error exit * Fix comment
This commit is contained in:
parent
030a0d464b
commit
03d23eb577
@ -25,11 +25,16 @@ object ValueModel {
|
||||
def errorCode(error: VarModel): Option[VarModel] =
|
||||
error.intoField("error_code")
|
||||
|
||||
def errorMessage(error: VarModel): Option[VarModel] =
|
||||
error.intoField("message")
|
||||
|
||||
val error = VarModel.fromVarRaw(ValueRaw.error)
|
||||
val errorType = ValueRaw.errorType
|
||||
|
||||
// NOTE: It should be safe as `:error:` should have `error_code` field
|
||||
val lastErrorCode = errorCode(error).get
|
||||
// NOTE: It should be safe as `:error:` should have `message` field
|
||||
val lastErrorMessage = errorMessage(error).get
|
||||
|
||||
implicit object ValueModelEq extends Eq[ValueModel] {
|
||||
override def eqv(x: ValueModel, y: ValueModel): Boolean = x == y
|
||||
|
@ -1,23 +1,15 @@
|
||||
package aqua.model.transform.funcop
|
||||
|
||||
import cats.data.Chain
|
||||
|
||||
import cats.Eval
|
||||
|
||||
import aqua.model.{
|
||||
CallModel,
|
||||
CallServiceModel,
|
||||
LiteralModel,
|
||||
MetaModel,
|
||||
OpModel,
|
||||
SeqModel,
|
||||
ValueModel
|
||||
}
|
||||
import aqua.model.*
|
||||
import aqua.model.transform.pre.InitPeerCallable
|
||||
import aqua.model.ParModel
|
||||
import aqua.model.DetachModel
|
||||
import aqua.model.transform.TransformConfig.TracingConfig
|
||||
|
||||
import cats.data.Chain
|
||||
import cats.Eval
|
||||
import aqua.types.ScalarType
|
||||
|
||||
final case class Tracing(
|
||||
enabledConfig: Option[TracingConfig],
|
||||
initCallable: InitPeerCallable
|
||||
@ -41,18 +33,39 @@ final case class Tracing(
|
||||
.fold(child)(traceCall =>
|
||||
/* seq:
|
||||
detach: call tracing enter
|
||||
<call-arrow-code>
|
||||
detach: call tracing exit */
|
||||
xor:
|
||||
seq:
|
||||
<call-arrow-code>
|
||||
detach: call tracing exit
|
||||
seq:
|
||||
call tracing error exit
|
||||
rethrow error
|
||||
*/
|
||||
SeqModel.wrap(
|
||||
DetachModel.wrap(
|
||||
initCallable.onInitPeer.wrap(
|
||||
traceCall(Event.Enter)
|
||||
)
|
||||
),
|
||||
child,
|
||||
DetachModel.wrap(
|
||||
initCallable.onInitPeer.wrap(
|
||||
traceCall(Event.Exit)
|
||||
XorModel.wrap(
|
||||
SeqModel.wrap(
|
||||
child,
|
||||
DetachModel.wrap(
|
||||
initCallable.onInitPeer.wrap(
|
||||
traceCall(Event.Exit)
|
||||
)
|
||||
)
|
||||
),
|
||||
SeqModel.wrap(
|
||||
/**
|
||||
* NOTE: Here we don't wrap trace call
|
||||
* with detach because Aqua VM ignores
|
||||
* it if it is detached.
|
||||
*/
|
||||
initCallable.onInitPeer.wrap(
|
||||
traceCall(Event.ErrorExit)
|
||||
),
|
||||
FailModel(ValueModel.error).leaf
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -64,23 +77,47 @@ final case class Tracing(
|
||||
object Tracing {
|
||||
|
||||
enum Event {
|
||||
case Enter, Exit
|
||||
case Enter, Exit, ErrorExit
|
||||
|
||||
def toArg: ValueModel = LiteralModel.quote(this match {
|
||||
def toArg(suffix: String = ""): ValueModel = LiteralModel.quote((this match {
|
||||
case Enter => "enter"
|
||||
case Exit => "exit"
|
||||
})
|
||||
case ErrorExit => "exit with error"
|
||||
}) + suffix)
|
||||
}
|
||||
|
||||
def traceCallModel(config: TracingConfig, arrowName: String)(
|
||||
private def traceCallModel(config: TracingConfig, arrowName: String)(
|
||||
event: Event
|
||||
): OpModel.Tree =
|
||||
CallServiceModel(
|
||||
LiteralModel.quote(config.serviceId),
|
||||
config.serviceFuncName,
|
||||
CallModel(
|
||||
args = List(LiteralModel.quote(arrowName), event.toArg),
|
||||
exportTo = Nil
|
||||
)
|
||||
).leaf
|
||||
): OpModel.Tree = {
|
||||
val serviceCall = (msg: ValueModel) =>
|
||||
CallServiceModel(
|
||||
LiteralModel.quote(config.serviceId),
|
||||
config.serviceFuncName,
|
||||
CallModel(
|
||||
args = List(LiteralModel.quote(arrowName), msg),
|
||||
exportTo = Nil
|
||||
)
|
||||
).leaf
|
||||
|
||||
event match {
|
||||
case Event.ErrorExit =>
|
||||
val errorName = "-return-error-msg-"
|
||||
|
||||
RestrictionModel(
|
||||
errorName,
|
||||
ScalarType.string
|
||||
).wrap(
|
||||
CallServiceModel(
|
||||
LiteralModel.quote("op"),
|
||||
"concat_strings",
|
||||
CallModel(
|
||||
args = List(event.toArg(": "), ValueModel.lastErrorMessage),
|
||||
exportTo = List(CallModel.Export(errorName, ScalarType.string))
|
||||
)
|
||||
).leaf,
|
||||
serviceCall(VarModel(errorName, ScalarType.string))
|
||||
)
|
||||
case _ => serviceCall(event.toArg())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user