Skip to content

Commit

Permalink
Scenario: move Scenario Error Throwable to scenario package (#10075)
Browse files Browse the repository at this point in the history
com.daml.lf.speedy.SErrorScenario => com.daml.lf.scenario.Error

CHANGELOG_BEGIN
CHANGELOG_END
  • Loading branch information
remyhaemmerle-da authored Jun 28, 2021
1 parent 7521ec9 commit 3df2566
Show file tree
Hide file tree
Showing 15 changed files with 353 additions and 318 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import com.daml.lf.data.Ref
import com.daml.lf.data.Ref.ModuleName
import com.daml.lf.language.LanguageVersion
import com.daml.lf.scenario.api.v1.{Map => _, _}
import com.daml.lf.speedy.ScenarioRunner
import io.grpc.stub.StreamObserver
import io.grpc.{Status, StatusRuntimeException}
import io.grpc.netty.NettyServerBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import com.daml.lf.data.Ref.{DottedName, Identifier, ModuleName, PackageId, Qual
import com.daml.lf.engine.script.ledgerinteraction.{IdeLedgerClient, ScriptTimeMode}
import com.daml.lf.language.{Ast, LanguageVersion, Util => AstUtil}
import com.daml.lf.scenario.api.v1.{ScenarioModule => ProtoScenarioModule}
import com.daml.lf.speedy.{Compiler, ScenarioRunner, SDefinition, SExpr, Speedy}
import com.daml.lf.speedy.SError._
import com.daml.lf.speedy.{Compiler, SDefinition, SExpr, Speedy}
import com.daml.lf.speedy.SExpr.{LfDefRef, SDefinitionRef}
import com.daml.lf.validation.Validation
import com.google.protobuf.ByteString
Expand Down Expand Up @@ -201,7 +200,7 @@ class Context(val contextId: Context.ContextId, languageVersion: LanguageVersion
val participants = Participants(Some(ledgerClient), Map.empty, Map.empty)
val (clientMachine, resultF) = runner.runWithClients(participants, traceLog)

def handleFailure(e: SError) = {
def handleFailure(e: Error) =
// SError are the errors that should be handled and displayed as
// failed partial transactions.
Success(
Expand All @@ -216,7 +215,6 @@ class Context(val contextId: Context.ContextId, languageVersion: LanguageVersion
)
)
)
}

val dummyDuration: Double = 0
val dummySteps: Int = 0
Expand All @@ -234,10 +232,11 @@ class Context(val contextId: Context.ContextId, languageVersion: LanguageVersion
)
)
)
case Failure(e: SError) => handleFailure(e)
case Failure(e: Error) => handleFailure(e)
case Failure(e: ScriptF.FailedCmd) =>
e.cause match {
case e: SError => handleFailure(e)
case e: Error => handleFailure(e)
case e: speedy.SError.SError => handleFailure(Error.RunnerException(e))
case _ => Failure(e)
}
case Failure(e) => Failure(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ final class Conversions(
builder.build
}

def convertScenarioError(
err: SError.SError
): proto.ScenarioError = {
def convertScenarioError(err: Error): proto.ScenarioError = {
val builder = proto.ScenarioError.newBuilder
.addAllNodes(nodes.asJava)
.addAllScenarioSteps(steps.asJava)
Expand All @@ -85,108 +83,113 @@ final class Conversions(
)

err match {
case SError.SErrorCrash(reason) => setCrash(reason)

case SError.SRequiresOnLedger(operation) => setCrash(operation)

case SError.SErrorDamlException(interpretationError) =>
import interpretation.Error._
interpretationError match {
case UnhandledException(_, value) =>
builder.setUnhandledException(convertValue(value))
case UserError(msg) =>
builder.setUserError(msg)
case ContractNotFound(cid) =>
// TODO https://github.com/digital-asset/daml/issues/9974
// We crash here because:
// 1. You cannot construct a cid yourself in scenarios or
// daml script
// 2. Contract id fetch failures because a contract was
// archived or what not are turned into more specific
// errors so we never produce ContractNotFound
builder.setCrash(s"contract ${cid.coid} not found")
case TemplatePreconditionViolated(tid, optLoc, arg) =>
val uepvBuilder = proto.ScenarioError.TemplatePreconditionViolated.newBuilder
optLoc.map(convertLocation).foreach(uepvBuilder.setLocation)
builder.setTemplatePrecondViolated(
uepvBuilder
.setTemplateId(convertIdentifier(tid))
.setArg(convertValue(arg))
.build
)
case ContractNotActive(coid, tid, consumedBy) =>
builder.setUpdateLocalContractNotActive(
proto.ScenarioError.ContractNotActive.newBuilder
.setContractRef(mkContractRef(coid, tid))
.setConsumedBy(proto.NodeId.newBuilder.setId(consumedBy.toString).build)
.build
)
case LocalContractKeyNotVisible(coid, gk, actAs, readAs, stakeholders) =>
builder.setScenarioContractKeyNotVisible(
proto.ScenarioError.ContractKeyNotVisible.newBuilder
.setContractRef(mkContractRef(coid, gk.templateId))
.addAllActAs(actAs.map(convertParty(_)).asJava)
.addAllReadAs(readAs.map(convertParty(_)).asJava)
.addAllStakeholders(stakeholders.map(convertParty).asJava)
.build
)
case ContractKeyNotFound(gk) =>
builder.setScenarioContractKeyNotFound(
proto.ScenarioError.ContractKeyNotFound.newBuilder
.setTemplateId(convertIdentifier(gk.templateId))
.setKey(convertValue(gk.key))
.build
)
case DuplicateContractKey(key) =>
builder.setScenarioCommitError(
proto.CommitError.newBuilder.setUniqueKeyViolation(convertGlobalKey(key)).build
)
case CreateEmptyContractKeyMaintainers(tid, arg, key) =>
builder.setCreateEmptyContractKeyMaintainers(
proto.ScenarioError.CreateEmptyContractKeyMaintainers.newBuilder
.setArg(convertValue(arg))
.setTemplateId(convertIdentifier(tid))
.setKey(convertValue(key))
)
case FetchEmptyContractKeyMaintainers(tid, key) =>
builder.setFetchEmptyContractKeyMaintainers(
proto.ScenarioError.FetchEmptyContractKeyMaintainers.newBuilder
.setTemplateId(convertIdentifier(tid))
.setKey(convertValue(key))
)
case wtc: WronglyTypedContract =>
// TODO https://github.com/digital-asset/daml/issues/9974
// (MK) This isn’t actually true. You can easily
// coerceContractId your way into this error. Not for
// this PR though.
sys.error(
s"Got unexpected DamlEWronglyTypedContract error in scenario service: $wtc. Note that in the scenario service this error should never surface since contract fetches are all type checked."
)
case FailedAuthorization(nid, fa) =>
builder.setScenarioCommitError(
proto.CommitError.newBuilder
.setFailedAuthorizations(convertFailedAuthorization(nid, fa))
.build
)

case Error.Internal(reason) => setCrash(reason)

case Error.RunnerException(serror) =>
serror match {
case SError.SErrorCrash(reason) => setCrash(reason)

case SError.SRequiresOnLedger(operation) => setCrash(operation)

case SError.SErrorDamlException(interpretationError) =>
import interpretation.Error._
interpretationError match {
case UnhandledException(_, value) =>
builder.setUnhandledException(convertValue(value))
case UserError(msg) =>
builder.setUserError(msg)
case ContractNotFound(cid) =>
// TODO https://github.com/digital-asset/daml/issues/9974
// We crash here because:
// 1. You cannot construct a cid yourself in scenarios or
// daml script
// 2. Contract id fetch failures because a contract was
// archived or what not are turned into more specific
// errors so we never produce ContractNotFound
builder.setCrash(s"contract ${cid.coid} not found")
case TemplatePreconditionViolated(tid, optLoc, arg) =>
val uepvBuilder = proto.ScenarioError.TemplatePreconditionViolated.newBuilder
optLoc.map(convertLocation).foreach(uepvBuilder.setLocation)
builder.setTemplatePrecondViolated(
uepvBuilder
.setTemplateId(convertIdentifier(tid))
.setArg(convertValue(arg))
.build
)
case ContractNotActive(coid, tid, consumedBy) =>
builder.setUpdateLocalContractNotActive(
proto.ScenarioError.ContractNotActive.newBuilder
.setContractRef(mkContractRef(coid, tid))
.setConsumedBy(proto.NodeId.newBuilder.setId(consumedBy.toString).build)
.build
)
case LocalContractKeyNotVisible(coid, gk, actAs, readAs, stakeholders) =>
builder.setScenarioContractKeyNotVisible(
proto.ScenarioError.ContractKeyNotVisible.newBuilder
.setContractRef(mkContractRef(coid, gk.templateId))
.addAllActAs(actAs.map(convertParty(_)).asJava)
.addAllReadAs(readAs.map(convertParty(_)).asJava)
.addAllStakeholders(stakeholders.map(convertParty).asJava)
.build
)
case ContractKeyNotFound(gk) =>
builder.setScenarioContractKeyNotFound(
proto.ScenarioError.ContractKeyNotFound.newBuilder
.setTemplateId(convertIdentifier(gk.templateId))
.setKey(convertValue(gk.key))
.build
)
case DuplicateContractKey(key) =>
builder.setScenarioCommitError(
proto.CommitError.newBuilder.setUniqueKeyViolation(convertGlobalKey(key)).build
)
case CreateEmptyContractKeyMaintainers(tid, arg, key) =>
builder.setCreateEmptyContractKeyMaintainers(
proto.ScenarioError.CreateEmptyContractKeyMaintainers.newBuilder
.setArg(convertValue(arg))
.setTemplateId(convertIdentifier(tid))
.setKey(convertValue(key))
)
case FetchEmptyContractKeyMaintainers(tid, key) =>
builder.setFetchEmptyContractKeyMaintainers(
proto.ScenarioError.FetchEmptyContractKeyMaintainers.newBuilder
.setTemplateId(convertIdentifier(tid))
.setKey(convertValue(key))
)
case wtc: WronglyTypedContract =>
// TODO https://github.com/digital-asset/daml/issues/9974
// (MK) This isn’t actually true. You can easily
// coerceContractId your way into this error. Not for
// this PR though.
sys.error(
s"Got unexpected DamlEWronglyTypedContract error in scenario service: $wtc. Note that in the scenario service this error should never surface since contract fetches are all type checked."
)
case FailedAuthorization(nid, fa) =>
builder.setScenarioCommitError(
proto.CommitError.newBuilder
.setFailedAuthorizations(convertFailedAuthorization(nid, fa))
.build
)

}
}
case SError.ScenarioErrorContractNotEffective(coid, tid, effectiveAt) =>
case Error.ContractNotEffective(coid, tid, effectiveAt) =>
builder.setScenarioContractNotEffective(
proto.ScenarioError.ContractNotEffective.newBuilder
.setEffectiveAt(effectiveAt.micros)
.setContractRef(mkContractRef(coid, tid))
.build
)

case SError.ScenarioErrorContractNotActive(coid, tid, consumedBy) =>
case Error.ContractNotActive(coid, tid, consumedBy) =>
builder.setScenarioContractNotActive(
proto.ScenarioError.ContractNotActive.newBuilder
.setContractRef(mkContractRef(coid, tid))
.setConsumedBy(convertEventId(consumedBy))
.build
)

case SError.ScenarioErrorContractNotVisible(coid, tid, actAs, readAs, observers) =>
case Error.ContractNotVisible(coid, tid, actAs, readAs, observers) =>
builder.setScenarioContractNotVisible(
proto.ScenarioError.ContractNotVisible.newBuilder
.setContractRef(mkContractRef(coid, tid))
Expand All @@ -196,7 +199,7 @@ final class Conversions(
.build
)

case SError.ScenarioErrorContractKeyNotVisible(coid, gk, actAs, readAs, stakeholders) =>
case Error.ContractKeyNotVisible(coid, gk, actAs, readAs, stakeholders) =>
builder.setScenarioContractKeyNotVisible(
proto.ScenarioError.ContractKeyNotVisible.newBuilder
.setContractRef(mkContractRef(coid, gk.templateId))
Expand All @@ -207,17 +210,17 @@ final class Conversions(
.build
)

case SError.ScenarioErrorCommitError(commitError) =>
case Error.CommitError(commitError) =>
builder.setScenarioCommitError(
convertCommitError(commitError)
)
case SError.ScenarioErrorMustFailSucceeded(tx @ _) =>
case Error.MustFailSucceeded(tx @ _) =>
builder.setScenarioMustfailSucceeded(empty)

case SError.ScenarioErrorInvalidPartyName(party, _) =>
case Error.InvalidPartyName(party, _) =>
builder.setScenarioInvalidPartyName(party)

case SError.ScenarioErrorPartyAlreadyExists(party) =>
case Error.PartyAlreadyExists(party) =>
builder.setScenarioPartyAlreadyExists(party)
}
builder.build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ class Engine(val config: EngineConfig = new EngineConfig(LanguageVersion.StableV
case SResultError(err) =>
return ResultError(
Error.Interpretation.Generic(
s"Interpretation error: ${Pretty.prettyError(err, onLedger.ptxInternal).render(80)}"
s"Interpretation error: ${Pretty.prettyError(err, Some(onLedger.ptxInternal)).render(80)}"
),
detailMsg,
)
Expand Down
Loading

0 comments on commit 3df2566

Please sign in to comment.