Skip to content

Commit

Permalink
More missing error codes (#11749)
Browse files Browse the repository at this point in the history
* Missing error codes in Sandbox classic

CHANGELOG_BEGIN
CHANGELOG_END

* Covering more errors above the persistence layer

* Fix wrong contextualizedErrorLoggers

* Compilation fixes
  • Loading branch information
tudor-da authored Nov 18, 2021
1 parent 3366413 commit b0a1bf7
Show file tree
Hide file tree
Showing 26 changed files with 410 additions and 189 deletions.
2 changes: 2 additions & 0 deletions docs/source/error-codes/self-service/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ The following gRPC status codes have changed for submission rejections in Sandbo
+-----------------------------------+---------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------+
|ABORTED |NOT_FOUND |NOT_FOUND is now returned on transaction rejections on not found contract. |CONTRACT_NOT_FOUND |
+-----------------------------------+---------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------+
|ABORTED |NOT_FOUND |NOT_FOUND is now returned on rejections occurring due to missing ledger configuration. |LEDGER_CONFIGURATION_NOT_FOUND |
+-----------------------------------+---------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------+
|INVALID_ARGUMENT |INTERNAL |INTERNAL is now returned on transaction rejections on system faults. |DISPUTED |
+-----------------------------------+---------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------+
|INVALID_ARGUMENT |NOT_FOUND |PARTY_NOT_KNOWN_ON_LEDGER is now returned on transaction rejections on unallocated parties. |PARTY_NOT_KNOWN_ON_LEDGER |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ object IndexErrors extends IndexErrorGroup {
throwableO = Some(throwable),
)
}

@Explanation(
"This error occurs if the result set returned by a query against the Index database is invalid."
)
@Resolution("Contact support.")
object ResultSetError
extends ErrorCode(
id = "INDEX_DB_INVALID_RESULT_SET",
ErrorCategory.SystemInternalAssumptionViolated,
)
with HasUnapply {
case class Reject(message: String)(implicit
val loggingContext: ContextualizedErrorLogger
) extends LoggingTransactionErrorImpl(
cause = message
)
}
}

trait HasUnapply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,12 @@ object LedgerApiErrors extends LedgerApiErrorGroup {
) extends LoggingTransactionErrorImpl(
cause = "The ledger configuration could not be retrieved."
)

case class RejectWithMessage(message: String)(implicit
loggingContext: ContextualizedErrorLogger
) extends LoggingTransactionErrorImpl(
cause = s"The ledger configuration could not be retrieved: $message."
)
}
}

Expand Down Expand Up @@ -594,6 +600,10 @@ object LedgerApiErrors extends LedgerApiErrorGroup {
case class VersionService(message: String)(implicit
loggingContext: ContextualizedErrorLogger
) extends LoggingTransactionErrorImpl(cause = message)

case class Buffer(message: String, override val throwableO: Option[Throwable])(implicit
loggingContext: ContextualizedErrorLogger
) extends LoggingTransactionErrorImpl(cause = message, throwableO = throwableO)
}

object AdminServices {
Expand Down Expand Up @@ -770,12 +780,14 @@ object LedgerApiErrors extends LedgerApiErrorGroup {
ErrorCategory.InvalidGivenCurrentSystemStateOther, // It may succeed at a later time
) {
case class RejectEnriched(
details: String,
message: String,
ledger_time: Instant,
ledger_time_lower_bound: Instant,
ledger_time_upper_bound: Instant,
)(implicit loggingContext: ContextualizedErrorLogger)
extends LoggingTransactionErrorImpl(cause = s"Invalid ledger time: $details")
extends LoggingTransactionErrorImpl(
cause = s"Invalid ledger time: $message"
)

case class RejectSimple(
details: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ object CompletionResponse {
val statusBuilder = GrpcStatus.toJavaBuilder(notOkResponse.grpcStatus)
GrpcStatus.buildStatus(metadata, statusBuilder)
case CompletionResponse.TimeoutResponse(_) =>
errorFactories.TrackerErrors.timedOutOnAwaitingForCommandCompletion()
errorFactories.SubmissionQueueErrors.timedOutOnAwaitingForCommandCompletion()
case CompletionResponse.NoStatusInResponse(_) =>
errorFactories.TrackerErrors.noStatusInCompletionResponse()
errorFactories.SubmissionQueueErrors.noStatusInCompletionResponse()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ import io.grpc.{Metadata, StatusRuntimeException}
import scalaz.syntax.tag._

import java.sql.{SQLNonTransientException, SQLTransientException}
import java.time.Duration
import java.time.{Duration, Instant}
import scala.annotation.nowarn

class ErrorFactories private (errorCodesVersionSwitcher: ErrorCodesVersionSwitcher) {
object TrackerErrors {
object SubmissionQueueErrors {
def failedToEnqueueCommandSubmission(message: String)(t: Throwable)(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): Status =
Expand All @@ -50,22 +50,7 @@ class ErrorFactories private (errorCodesVersionSwitcher: ErrorCodesVersionSwitch
.asGrpcStatusFromContext,
)

def commandServiceIngressBufferFull()(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): Status =
errorCodesVersionSwitcher.choose(
v1 = {
val status = io.grpc.Status.RESOURCE_EXHAUSTED
.withDescription("Ingress buffer is full")
val statusBuilder = GrpcStatus.toJavaBuilder(status)
GrpcStatus.buildStatus(Map.empty, statusBuilder)
},
v2 = LedgerApiErrors.ParticipantBackpressure
.Rejection("Command service ingress buffer is full")
.asGrpcStatusFromContext,
)

def commandSubmissionQueueClosed()(implicit
def queueClosed(queueName: String)(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): Status =
errorCodesVersionSwitcher.choose(
Expand All @@ -75,7 +60,7 @@ class ErrorFactories private (errorCodesVersionSwitcher: ErrorCodesVersionSwitch
GrpcStatus.buildStatus(Map.empty, statusBuilder)
},
v2 = LedgerApiErrors.ServiceNotRunning
.Reject("Command service submission queue")
.Reject(queueName)
.asGrpcStatusFromContext,
)

Expand Down Expand Up @@ -117,6 +102,21 @@ class ErrorFactories private (errorCodesVersionSwitcher: ErrorCodesVersionSwitch
}
}

def bufferFull(message: String)(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): Status =
errorCodesVersionSwitcher.choose(
v1 = {
val status = io.grpc.Status.RESOURCE_EXHAUSTED
.withDescription("Ingress buffer is full")
val statusBuilder = GrpcStatus.toJavaBuilder(status)
GrpcStatus.buildStatus(Map.empty, statusBuilder)
},
v2 = LedgerApiErrors.ParticipantBackpressure
.Rejection(message)
.asGrpcStatusFromContext,
)

def sqlTransientException(exception: SQLTransientException)(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): StatusRuntimeException =
Expand Down Expand Up @@ -477,6 +477,21 @@ class ErrorFactories private (errorCodesVersionSwitcher: ErrorCodesVersionSwitch
.asGrpcError,
)

def missingLedgerConfig(
v1Status: RpcStatus,
message: String,
)(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): com.google.rpc.status.Status =
errorCodesVersionSwitcher.choose(
v1 = v1Status,
v2 = GrpcStatus.toProto(
LedgerApiErrors.RequestValidation.NotFound.LedgerConfiguration
.RejectWithMessage(message)
.asGrpcStatusFromContext
),
)

def participantPrunedDataAccessed(message: String)(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): StatusRuntimeException =
Expand Down Expand Up @@ -686,6 +701,31 @@ class ErrorFactories private (errorCodesVersionSwitcher: ErrorCodesVersionSwitch
),
)

def invalidLedgerTime(
v1Status: RpcStatus,
ledgerTime: Instant,
ledgerTimeLowerBound: Instant,
ledgerTimeUpperBound: Instant,
)(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): com.google.rpc.status.Status = {
val details =
s"Ledger time $ledgerTime outside of range [$ledgerTimeLowerBound, $ledgerTimeUpperBound]"
errorCodesVersionSwitcher.choose(
v1 = v1Status,
v2 = GrpcStatus.toProto(
LedgerApiErrors.ConsistencyErrors.InvalidLedgerTime
.RejectEnriched(
details,
ledgerTime,
ledgerTimeLowerBound,
ledgerTimeUpperBound,
)
.asGrpcStatusFromContext
),
)
}

def inconsistent(reason: String)(implicit
contextualizedErrorLogger: ContextualizedErrorLogger
): com.google.rpc.status.Status =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class ErrorFactoriesSpec
"return failedToEnqueueCommandSubmission" in {
val t = new Exception("message123")
assertVersionedStatus(
_.TrackerErrors.failedToEnqueueCommandSubmission("some message")(t)(
_.SubmissionQueueErrors.failedToEnqueueCommandSubmission("some message")(t)(
contextualizedErrorLogger
)
)(
Expand All @@ -107,18 +107,16 @@ class ErrorFactoriesSpec
)
}

"return ingressBufferFull" in {
"return bufferFul" in {
assertVersionedStatus(
_.TrackerErrors.commandServiceIngressBufferFull()(
contextualizedErrorLogger = contextualizedErrorLogger
)
_.bufferFull("Some buffer is full")(contextualizedErrorLogger)
)(
v1_code = Code.RESOURCE_EXHAUSTED,
v1_message = "Ingress buffer is full",
v1_details = Seq(errorDetails),
v2_code = Code.ABORTED,
v2_message =
s"PARTICIPANT_BACKPRESSURE(2,$truncatedCorrelationId): The participant is overloaded: Command service ingress buffer is full",
s"PARTICIPANT_BACKPRESSURE(2,$truncatedCorrelationId): The participant is overloaded: Some buffer is full",
v2_details = Seq[ErrorDetails.ErrorDetail](
ErrorDetails.ErrorInfoDetail("PARTICIPANT_BACKPRESSURE"),
expectedCorrelationIdRequestInfo,
Expand All @@ -129,7 +127,7 @@ class ErrorFactoriesSpec

"return queueClosed" in {
assertVersionedStatus(
_.TrackerErrors.commandSubmissionQueueClosed()(
_.SubmissionQueueErrors.queueClosed("Some service")(
contextualizedErrorLogger = contextualizedErrorLogger
)
)(
Expand All @@ -138,7 +136,7 @@ class ErrorFactoriesSpec
v1_details = Seq(errorDetails),
v2_code = Code.UNAVAILABLE,
v2_message =
s"SERVICE_NOT_RUNNING(1,$truncatedCorrelationId): Command service submission queue has been shut down.",
s"SERVICE_NOT_RUNNING(1,$truncatedCorrelationId): Some service has been shut down.",
v2_details = Seq[ErrorDetails.ErrorDetail](
ErrorDetails.ErrorInfoDetail("SERVICE_NOT_RUNNING"),
expectedCorrelationIdRequestInfo,
Expand All @@ -149,7 +147,7 @@ class ErrorFactoriesSpec

"return timeout" in {
assertVersionedStatus(
_.TrackerErrors.timedOutOnAwaitingForCommandCompletion()(
_.SubmissionQueueErrors.timedOutOnAwaitingForCommandCompletion()(
contextualizedErrorLogger = contextualizedErrorLogger
)
)(
Expand All @@ -168,7 +166,7 @@ class ErrorFactoriesSpec
}
"return noStatusInResponse" in {
assertVersionedStatus(
_.TrackerErrors.noStatusInCompletionResponse()(
_.SubmissionQueueErrors.noStatusInCompletionResponse()(
contextualizedErrorLogger = contextualizedErrorLogger
)
)(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ object domain {
/** The ledger time of the submission violated some constraint on the ledger time. */
final case class InvalidLedgerTime(description: String) extends RejectionReason

final case class LedgerConfigNotFound(description: String) extends RejectionReason

/** The transaction relied on contracts being active that were no longer
* active at the point where it was sequenced.
*/
Expand Down
1 change: 1 addition & 0 deletions ledger/participant-integration-api/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ compile_deps = [
"//libs-scala/build-info",
"//libs-scala/contextualized-logging",
"//libs-scala/concurrent",
"//libs-scala/grpc-utils",
"//libs-scala/logging-entries",
"//libs-scala/ports",
"//libs-scala/resources",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ private[apiserver] final class LedgerTimeAwareCommandExecutor(
}
}
.recoverWith {

case MissingContracts(contracts) =>
if (retriesLeft > 0) {
metrics.daml.execution.retry.mark()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,6 @@ private[apiserver] object ApiPartyManagementService {
PartyEntry.AllocationAccepted,
] {
private val logger = ContextualizedLogger.get(getClass)
private implicit val contextualizedErrorLogger: ContextualizedErrorLogger =
new DamlContextualizedErrorLogger(logger, loggingContext, None)

override def currentLedgerEnd(): Future[Option[LedgerOffset.Absolute]] =
ledgerEndService.currentLedgerEnd().map(Some(_))
Expand All @@ -227,7 +225,9 @@ private[apiserver] object ApiPartyManagementService {
submissionId: Ref.SubmissionId
): PartialFunction[PartyEntry, StatusRuntimeException] = {
case PartyEntry.AllocationRejected(`submissionId`, reason) =>
errorFactories.invalidArgument(None)(reason)
errorFactories.invalidArgument(None)(reason)(
new DamlContextualizedErrorLogger(logger, loggingContext, Some(submissionId))
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,23 @@ private[services] final class QueueBackedTracker(
)
case QueueOfferResult.Failure(t) =>
toQueueSubmitFailure(
errorFactories.TrackerErrors.failedToEnqueueCommandSubmission("Failed to enqueue")(t)
errorFactories.SubmissionQueueErrors
.failedToEnqueueCommandSubmission("Failed to enqueue")(t)
)
case QueueOfferResult.Dropped =>
toQueueSubmitFailure(errorFactories.TrackerErrors.commandServiceIngressBufferFull())
toQueueSubmitFailure(errorFactories.bufferFull("The submission ingress buffer is full"))
case QueueOfferResult.QueueClosed =>
toQueueSubmitFailure(errorFactories.TrackerErrors.commandSubmissionQueueClosed())
toQueueSubmitFailure(
errorFactories.SubmissionQueueErrors.queueClosed("Command service queue")
)
}
.recoverWith {
case i: IllegalStateException
if i.getMessage == "You have to wait for previous offer to be resolved to send another request" =>
toQueueSubmitFailure(errorFactories.TrackerErrors.commandServiceIngressBufferFull())
toQueueSubmitFailure(errorFactories.bufferFull("The submission ingress buffer is full"))
case t =>
toQueueSubmitFailure(
errorFactories.TrackerErrors.failedToEnqueueCommandSubmission("Failed")(t)
errorFactories.SubmissionQueueErrors.failedToEnqueueCommandSubmission("Failed")(t)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package com.daml.platform.store
import anorm.Column.nonNull
import anorm._
import com.daml.error.ContextualizedErrorLogger
import com.daml.error.definitions.LedgerApiErrors
import com.daml.grpc.GrpcStatus
import com.daml.ledger.api.domain
import com.daml.ledger.offset.Offset
import com.daml.ledger.participant.state.v2.Update.CommandRejected
Expand All @@ -22,7 +24,6 @@ import scala.util.Try
import java.io.BufferedReader
import java.sql.{PreparedStatement, SQLNonTransientException, Types}
import java.util.stream.Collectors

import scala.annotation.nowarn

// TODO append-only: split this file on cleanup, and move anorm/db conversion related stuff to the right place
Expand Down Expand Up @@ -426,6 +427,16 @@ private[platform] object Conversions {
CommandRejected.FinalReason(
errorFactories.CommandRejections.invalidLedgerTime(reason)
)
case domain.RejectionReason.LedgerConfigNotFound(description) =>
// This rejection is returned only for V2 error codes already so we don't need to
// wrap it in ErrorFactories (see [[com.daml.platform.sandbox.stores.ledger.Rejection.NoLedgerConfiguration]]
CommandRejected.FinalReason(
GrpcStatus.toProto(
LedgerApiErrors.RequestValidation.NotFound.LedgerConfiguration
.RejectWithMessage(description)
.asGrpcStatusFromContext
)
)
}
}
}
Loading

0 comments on commit b0a1bf7

Please sign in to comment.