Skip to content

Commit

Permalink
[DPP-417][DPP-613] Adopt self-service error codes ApiTransactionServi…
Browse files Browse the repository at this point in the history
…ce (initial version)
  • Loading branch information
pbatko-da committed Oct 4, 2021
1 parent a8d703b commit adc79ae
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ object ErrorResource {
object ContractKey extends ErrorResource {
def asString: String = "contract-key"
}
object TransactionId extends ErrorResource {
def asString: String = "transaction-id"
}
object DalfPackage extends ErrorResource {
def asString: String = "lf-package"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,33 @@ object LedgerApiErrors extends LedgerApiErrorGroup {

}

@Explanation(
"""TODO: Explanations needs yet to be filled out"""
)
@Resolution("TODO: Resolution needs yet to be filled out")
object TransactionNotFound
extends ErrorCode(
id = "TRANSACTION_NOT_FOUND",
ErrorCategory.InvalidGivenCurrentSystemStateResourceMissing,
) {

case class Reject(
override val cause: String,
transactionId: String,
)(implicit
loggingContext: LoggingContext,
logger: ContextualizedLogger,
correlationId: CorrelationId,
) extends LoggingTransactionErrorImpl(
cause = cause
) {
override def resources: Seq[(ErrorResource, String)] = Seq(
(ErrorResource.ContractKey, transactionId)
)
}

}

}

@Explanation("""This error occurs if the Daml transaction fails due to an authorization error.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import com.daml.logging.{ContextualizedLogger, LoggingContext}
import com.daml.metrics.Metrics
import com.daml.platform.apiserver.ErrorCodesVersionSwitcher
import com.daml.platform.apiserver.error.{CorrelationId, LedgerApiErrors}
import com.daml.platform.apiserver.services.transaction.ApiTransactionService._
import com.daml.platform.apiserver.services.{StreamMetrics, logging}
import com.daml.platform.server.api.services.domain.TransactionService
import com.daml.platform.server.api.services.grpc.GrpcTransactionService
Expand All @@ -58,14 +57,6 @@ private[apiserver] object ApiTransactionService {
ledgerId,
PartyNameChecker.AllowAllParties,
)

@throws[StatusRuntimeException]
private def getOrElseThrowNotFound[A](a: Option[A]): A =
a.getOrElse(
throw Status.NOT_FOUND
.withDescription("Transaction not found, or not visible.")
.asRuntimeException()
)
}

private[apiserver] final class ApiTransactionService private (
Expand Down Expand Up @@ -191,9 +182,19 @@ private[apiserver] final class ApiTransactionService private (
.fromString(request.eventId.unwrap)
.fold(
err =>
Future.failed[GetFlatTransactionResponse](
Status.NOT_FOUND.withDescription(s"invalid eventId: $err").asRuntimeException()
),
Future.failed[GetFlatTransactionResponse] {
val msg = s"invalid eventId: $err"
errorsVersionsSwitcher.choose(
v1 = Status.NOT_FOUND.withDescription(msg).asRuntimeException(),
v2 = LedgerApiErrors.CommandValidation.InvalidArgument
.Reject(msg)(
correlationId = CorrelationId.none,
loggingContext = implicitly[LoggingContext],
logger = logger,
)
.asGrpcError,
)
},
eventId =>
lookUpFlatByTransactionId(
TransactionId(eventId.transactionId),
Expand Down Expand Up @@ -224,15 +225,38 @@ private[apiserver] final class ApiTransactionService private (
): Future[GetTransactionResponse] =
transactionsService
.getTransactionTreeById(transactionId, requestingParties)
.map(getOrElseThrowNotFound)
.map(getOrElseThrowNotFound(transactionId))

private def lookUpFlatByTransactionId(
transactionId: TransactionId,
requestingParties: Set[Party],
): Future[GetFlatTransactionResponse] =
): Future[GetFlatTransactionResponse] = {
transactionsService
.getTransactionById(transactionId, requestingParties)
.map(getOrElseThrowNotFound)
.map(getOrElseThrowNotFound(transactionId))
}

@throws[StatusRuntimeException]
private def getOrElseThrowNotFound[A](transactionId: TransactionId)(a: Option[A]): A =
a.getOrElse {
val msg = "Transaction not found, or not visible."
val exception = errorsVersionsSwitcher.choose(
v1 = Status.NOT_FOUND
.withDescription(msg)
.asRuntimeException(),
v2 = LedgerApiErrors.InterpreterErrors.LookupErrors.TransactionNotFound
.Reject(
cause = msg,
transactionId = transactionId.unwrap,
)(
correlationId = CorrelationId.none,
loggingContext = implicitly[LoggingContext],
logger = logger,
)
.asGrpcError,
)
throw exception
}

private def transactionsLoggable(transactions: GetTransactionsResponse): String =
s"Responding with transactions: ${transactions.transactions.toList
Expand Down

0 comments on commit adc79ae

Please sign in to comment.