diff --git a/build.sbt b/build.sbt index 7a5348bf34..19d35cc23a 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,7 @@ import sbtbuildinfo.BuildInfoPlugin.autoImport.* inThisBuild( Seq( organization := "org.hyperledger", - scalaVersion := "3.3.3", + scalaVersion := "3.4.0", fork := true, run / connectInput := true, releaseUseGlobalVersion := false, @@ -34,7 +34,7 @@ inThisBuild( "-unchecked", "-Dquill.macro.log=false", // disable quill macro logs "-Wunused:all", - "-Wconf:any:warning" // TODO: change unused imports to errors, Wconf configuration string is different from scala 2, figure out how! + "-Wconf:any:warning", // TODO: change unused imports to errors, Wconf configuration string is different from scala 2, figure out how! // TODO "-feature", // TODO "-Xfatal-warnings", // TODO "-Yexplicit-nulls", @@ -502,7 +502,8 @@ lazy val models = project ), // TODO try to remove this from this module // libraryDependencies += D.didScala ) - .settings(libraryDependencies += D.nimbusJwt) //FIXME just for the DidAgent + .settings(libraryDependencies += D.nimbusJwt) // FIXME just for the DidAgent + .dependsOn(shared) /* TODO move code from agentDidcommx to here models implementation for didcommx () */ @@ -841,6 +842,17 @@ lazy val cloudAgentServer = project .settings(commonSetttings) .settings( name := "identus-cloud-agent", + scalacOptions ++= Seq( + "-Yno-deep-subtypes", + "-Yno-decode-stacktraces", + "-Yno-patmat-opt", + "-Yshow-print-errors", + "-Ydetailed-stats", + // "-Xshow-phases", + // "-Xprint:all", + // "-Ydebug", + "-Ylog:all", + ), fork := true, libraryDependencies ++= D_CloudAgent.serverDependencies, excludeDependencies ++= Seq( diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/BackgroundJobError.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/BackgroundJobError.scala index 8cd4be569d..f9deec195f 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/BackgroundJobError.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/BackgroundJobError.scala @@ -1,15 +1,40 @@ package org.hyperledger.identus.agent.server.jobs import org.hyperledger.identus.mercury.HttpResponse +import org.hyperledger.identus.shared.models._ -sealed trait BackgroundJobError +sealed trait BackgroundJobError( + override val statusCode: org.hyperledger.identus.shared.models.StatusCode, + override val userFacingMessage: String +) extends Failure { + override val namespace: String = "BackgroundJobError" +} object BackgroundJobError { - final case class InvalidState(cause: String) extends BackgroundJobError - final case class ErrorSendingMessage(cause: String) extends BackgroundJobError - case object NotImplemented extends BackgroundJobError - final case class ErrorResponseReceivedFromPeerAgent(response: HttpResponse) extends BackgroundJobError { + final case class InvalidState(cause: String) + extends BackgroundJobError( + statusCode = StatusCode.FixmeStatusCode, + userFacingMessage = s"Invalid State: cause='$cause'" + ) + + final case class ErrorSendingMessage(cause: String) + extends BackgroundJobError( + statusCode = StatusCode.FixmeStatusCode, + userFacingMessage = s"ErrorSendingMessage" + ) + + case object NotImplemented + extends BackgroundJobError( + statusCode = StatusCode.FixmeStatusCode, + userFacingMessage = s"NotImplemented" + ) + final case class ErrorResponseReceivedFromPeerAgent(response: HttpResponse) + extends BackgroundJobError( + statusCode = StatusCode.FixmeStatusCode, + userFacingMessage = s"DIDComm sending error: [${response.status}] - ${response.bodyAsString}" + ) { + override def toString: String = s"DIDComm sending error: [${response.status}] - ${response.bodyAsString}" } } diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/ConnectBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/ConnectBackgroundJobs.scala index 483a7a6d87..c4bffda598 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/ConnectBackgroundJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/ConnectBackgroundJobs.scala @@ -6,10 +6,13 @@ import org.hyperledger.identus.agent.walletapi.model.error.DIDSecretStorageError import org.hyperledger.identus.agent.walletapi.model.error.DIDSecretStorageError.{KeyNotFoundError, WalletNotFoundError} import org.hyperledger.identus.agent.walletapi.service.ManagedDIDService import org.hyperledger.identus.agent.walletapi.storage.DIDNonSecretStorage +import org.hyperledger.identus.connect.core.model.error.ConnectionServiceError.InvalidStateForOperation +import org.hyperledger.identus.connect.core.model.error.ConnectionServiceError.RecordIdNotFound import org.hyperledger.identus.connect.core.model.ConnectionRecord import org.hyperledger.identus.connect.core.model.ConnectionRecord.* import org.hyperledger.identus.connect.core.service.ConnectionService import org.hyperledger.identus.mercury.* +import org.hyperledger.identus.mercury.error.SendMessageError import org.hyperledger.identus.resolvers.DIDResolver import org.hyperledger.identus.shared.models.WalletAccessContext import org.hyperledger.identus.shared.utils.aspects.CustomMetricsAspect @@ -120,12 +123,12 @@ object ConnectBackgroundJobs extends BackgroundJobsHelper { // inviteeProcessFlow // TODO decrease metaRetries if it has a error inviteeProcessFlow - @@ InviteeProcessConnectionRecordPendingSuccess.trackSuccess - @@ InviteeProcessConnectionRecordPendingFailed.trackError - @@ InviteeProcessConnectionRecordPendingTotal - @@ Metric - .gauge("connection_flow_invitee_process_connection_record_ms_gauge") - .trackDurationWith(_.toMetricsSeconds) + // @@ InviteeProcessConnectionRecordPendingSuccess.trackSuccess + // @@ InviteeProcessConnectionRecordPendingFailed.trackError + // @@ InviteeProcessConnectionRecordPendingTotal + // @@ Metric + // .gauge("connection_flow_invitee_process_connection_record_ms_gauge") + // .trackDurationWith(_.toMetricsSeconds) case ConnectionRecord( id, @@ -185,8 +188,15 @@ object ConnectBackgroundJobs extends BackgroundJobsHelper { case ((walletAccessContext, e)) => for { connectService <- ZIO.service[ConnectionService] + errorResponse: org.hyperledger.identus.shared.models.Failure = e match + case ex @ KeyNotFoundError(didId, keyId) => ex + case ex @ ErrorResponseReceivedFromPeerAgent(response) => ex + case ex @ SendMessageError(cause, mData) => ex + case ex @ RecordIdNotFound(recordId) => ex + case ex @ InvalidStateForOperation(state) => ex + // e: KeyNotFoundError | SendMessageError | (RecordIdNotFound | InvalidStateForOperation | ErrorResponseReceivedFromPeerAgent) _ <- connectService - .reportProcessingFailure(record.id, Some(e.toString)) + .reportProcessingFailure(record.id, Some(errorResponse)) .provideSomeLayer(ZLayer.succeed(walletAccessContext)) } yield () }) diff --git a/cloud-agent/service/wallet-api/src/main/scala/org/hyperledger/identus/agent/walletapi/model/error/DIDSecretStorageError.scala b/cloud-agent/service/wallet-api/src/main/scala/org/hyperledger/identus/agent/walletapi/model/error/DIDSecretStorageError.scala index 779d8fbde0..ecbb2813d2 100644 --- a/cloud-agent/service/wallet-api/src/main/scala/org/hyperledger/identus/agent/walletapi/model/error/DIDSecretStorageError.scala +++ b/cloud-agent/service/wallet-api/src/main/scala/org/hyperledger/identus/agent/walletapi/model/error/DIDSecretStorageError.scala @@ -1,10 +1,24 @@ package org.hyperledger.identus.agent.walletapi.model.error import org.hyperledger.identus.mercury.model.DidId +import org.hyperledger.identus.shared.models._ -sealed trait DIDSecretStorageError extends Throwable +sealed trait DIDSecretStorageError( + override val statusCode: StatusCode, + override val userFacingMessage: String +) extends Failure { + override val namespace: String = "DIDSecretStorageError" +} object DIDSecretStorageError { - case class KeyNotFoundError(didId: DidId, keyId: String) extends DIDSecretStorageError - case class WalletNotFoundError(didId: DidId) extends DIDSecretStorageError + case class KeyNotFoundError(didId: DidId, keyId: String) + extends DIDSecretStorageError( + StatusCode.FixmeStatusCode, + s"The not found: keyId='$keyId', didId='$didId'" + ) + case class WalletNotFoundError(didId: DidId) + extends DIDSecretStorageError( + StatusCode.FixmeStatusCode, + s"The DID not Found in Wallet: didId='$didId'" + ) } diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/model/ConnectionRecord.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/model/ConnectionRecord.scala index 13eccd9c81..5bb7700b58 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/model/ConnectionRecord.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/model/ConnectionRecord.scala @@ -42,7 +42,7 @@ case class ConnectionRecord( connectionResponse: Option[ConnectionResponse], metaRetries: Int, metaNextRetry: Option[Instant], - metaLastFailure: Option[String] + metaLastFailure: Option[org.hyperledger.identus.shared.models.Failure] ) { def withTruncatedTimestamp(unit: ChronoUnit = ChronoUnit.MICROS): ConnectionRecord = copy( createdAt = createdAt.truncatedTo(unit), diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/repository/ConnectionRepository.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/repository/ConnectionRepository.scala index 8407d4f751..85fa485081 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/repository/ConnectionRepository.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/repository/ConnectionRepository.scala @@ -67,7 +67,7 @@ trait ConnectionRepository { def updateAfterFail( recordId: UUID, - failReason: Option[String], + failReason: Option[org.hyperledger.identus.shared.models.Failure], ): URIO[WalletAccessContext, Unit] } diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/repository/ConnectionRepositoryInMemory.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/repository/ConnectionRepositoryInMemory.scala index 0ebb7d0a8c..1f0765477d 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/repository/ConnectionRepositoryInMemory.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/repository/ConnectionRepositoryInMemory.scala @@ -113,7 +113,7 @@ class ConnectionRepositoryInMemory(walletRefs: Ref[Map[WalletId, Ref[Map[UUID, C def updateAfterFail( recordId: UUID, - failReason: Option[String], + failReason: Option[org.hyperledger.identus.shared.models.Failure], ): URIO[WalletAccessContext, Unit] = for { maybeRecord <- findById(recordId) record <- ZIO.getOrFailWith(new RuntimeException(s"Record not found for Id: $recordId"))(maybeRecord).orDie @@ -131,7 +131,7 @@ class ConnectionRepositoryInMemory(walletRefs: Ref[Map[WalletId, Ref[Map[UUID, C def updateAfterFailForAllWallets( recordId: UUID, - failReason: Option[String], + failReason: Option[org.hyperledger.identus.shared.models.Failure], ): Task[Int] = walletRefs.get.flatMap { wallets => ZIO.foldLeft(wallets.values)(0) { (acc, walletRef) => for { diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionService.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionService.scala index 8cab80087f..80648cd328 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionService.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionService.scala @@ -86,6 +86,6 @@ trait ConnectionService { def reportProcessingFailure( recordId: UUID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] } diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala index 08f4bafb53..6f01e332a3 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala @@ -297,7 +297,7 @@ private class ConnectionServiceImpl( def reportProcessingFailure( recordId: UUID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = connectionRepository.updateAfterFail(recordId, failReason) diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceNotifier.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceNotifier.scala index 4aeec45ac5..72cd374a91 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceNotifier.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceNotifier.scala @@ -103,7 +103,7 @@ class ConnectionServiceNotifier( override def reportProcessingFailure( recordId: UUID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = svc.reportProcessingFailure(recordId, failReason) diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/MockConnectionService.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/MockConnectionService.scala index ddcc93828e..c1d8106744 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/MockConnectionService.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/MockConnectionService.scala @@ -126,7 +126,7 @@ object MockConnectionService extends Mock[ConnectionService] { override def reportProcessingFailure( recordId: UUID, - failReason: Option[String] + failReason: Option[org.hyperledger.identus.shared.models.Failure] ): URIO[WalletAccessContext, Unit] = ??? } } diff --git a/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala b/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala index def56b6df9..361bcb2e40 100644 --- a/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala +++ b/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala @@ -45,6 +45,9 @@ class JdbcConnectionRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ given connectionResponseGet: Get[ConnectionResponse] = Get[String].map(decode[ConnectionResponse](_).getOrElse(???)) given connectionResponsePut: Put[ConnectionResponse] = Put[String].contramap(_.asJson.toString) + given failureGet: Get[org.hyperledger.identus.shared.models.Failure] = ??? + given failurePut: Put[org.hyperledger.identus.shared.models.Failure] = ??? + override def create(record: ConnectionRecord): URIO[WalletAccessContext, Unit] = { val cxnIO = sql""" | INSERT INTO public.connection_records( @@ -327,7 +330,7 @@ class JdbcConnectionRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ def updateAfterFail( recordId: UUID, - failReason: Option[String], + failReason: Option[org.hyperledger.identus.shared.models.Failure], ): URIO[WalletAccessContext, Unit] = { val cxnIO = sql""" | UPDATE public.connection_records diff --git a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/error/package.scala b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/error/package.scala index 8d0b39acf0..87b1faf20c 100644 --- a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/error/package.scala +++ b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/error/package.scala @@ -1,11 +1,38 @@ package org.hyperledger.identus.mercury.model +import org.hyperledger.identus.shared.models._ + +import java.io.IOException + package object error { - sealed trait MercuryError + type MercuryException = MercuryError | IOException + type MercuryThrowable = MercuryError | IOException | Throwable // REMOVE Throwable + + def mercuryErrorAsThrowable(error: MercuryThrowable): java.lang.Throwable = error match + // case ex: MercuryError => + // ex match + // case te: TransportError => new RuntimeException(te) + case ex: MercuryError => ex.toUnmanagedFailureException + case ex: IOException => ex + case ex: Throwable => ex + + sealed trait MercuryError extends Failure { + override val namespace: String = "MercuryError" + } trait TransportError extends MercuryError - sealed case class SendMessageError(cause: Throwable, mData: Option[String] = None) extends TransportError + sealed case class SendMessageError(cause: Throwable, mData: Option[String] = None) + extends RuntimeException( + s"Error when sending message: ${cause.getMessage};${mData.map(e => s" DATA:'$e'").getOrElse("")}", + cause + ) + with TransportError { + override val statusCode = org.hyperledger.identus.shared.models.StatusCode.FixmeStatusCode + override val userFacingMessage = + s"Error when sending message: ${cause.getMessage};${mData.map(e => s" DATA:'$e'").getOrElse("")}. " + + cause.getMessage + } } diff --git a/shared/core/src/main/scala/org/hyperledger/identus/shared/models/Failure.scala b/shared/core/src/main/scala/org/hyperledger/identus/shared/models/Failure.scala index 3a895223f3..a23dd52afd 100644 --- a/shared/core/src/main/scala/org/hyperledger/identus/shared/models/Failure.scala +++ b/shared/core/src/main/scala/org/hyperledger/identus/shared/models/Failure.scala @@ -6,6 +6,8 @@ trait Failure { val namespace: String val statusCode: StatusCode val userFacingMessage: String + + def toUnmanagedFailureException = UnmanagedFailureException(this) } object Failure { @@ -31,4 +33,6 @@ object StatusCode { val InternalServerError: StatusCode = StatusCode(500) val BadGateway: StatusCode = StatusCode(502) + + val FixmeStatusCode: StatusCode = StatusCode(500) // FIXME TODO }