private async ValueTask <UserContact> TryCatch(ReturningUserContactFunction returningUserContactFunction)
        {
            try
            {
                return(await returningUserContactFunction());
            }
            catch (NullUserContactException nullUserContactException)
            {
                throw CreateAndLogValidationException(nullUserContactException);
            }
            catch (InvalidUserContactException invalidUserContactException)
            {
                throw CreateAndLogValidationException(invalidUserContactException);
            }
            catch (SqlException sqlException)
            {
                var failedUserContactStorageException =
                    new FailedUserContactStorageException(sqlException);

                throw CreateAndLogCriticalDependencyException(failedUserContactStorageException);
            }
            catch (NotFoundUserContactException notFoundUserContactException)
            {
                throw CreateAndLogValidationException(notFoundUserContactException);
            }
            catch (DuplicateKeyException duplicateKeyException)
            {
                var alreadyExistsUserContactException =
                    new AlreadyExistsUserContactException(duplicateKeyException);

                throw CreateAndLogValidationException(alreadyExistsUserContactException);
            }
            catch (ForeignKeyConstraintConflictException foreignKeyConstraintConflictException)
            {
                var invalidUserContactReferenceException =
                    new InvalidUserContactReferenceException(foreignKeyConstraintConflictException);

                throw CreateAndLogValidationException(invalidUserContactReferenceException);
            }
            catch (DbUpdateConcurrencyException dbUpdateConcurrencyException)
            {
                var lockedUserContactException =
                    new LockedUserContactException(dbUpdateConcurrencyException);

                throw CreateAndLogDependencyException(lockedUserContactException);
            }
            catch (DbUpdateException dbUpdateException)
            {
                var failedUserContactStorageException =
                    new FailedUserContactStorageException(dbUpdateException);

                throw CreateAndLogDependencyException(failedUserContactStorageException);
            }
            catch (Exception exception)
            {
                throw CreateAndLogServiceException(exception);
            }
        }
        public async void ShouldThrowValidationExceptionOnAddIfUserContactAlreadyExistsAndLogItAsync()
        {
            // given
            UserContact randomUserContact        = CreateRandomUserContact();
            UserContact alreadyExistsUserContact = randomUserContact;
            string      randomMessage            = GetRandomMessage();
            string      exceptionMessage         = randomMessage;
            var         duplicateKeyException    = new DuplicateKeyException(exceptionMessage);

            var alreadyExistsUserContactException =
                new AlreadyExistsUserContactException(duplicateKeyException);

            var expectedUserContactValidationException =
                new UserContactValidationException(alreadyExistsUserContactException);

            this.storageBrokerMock.Setup(broker =>
                                         broker.InsertUserContactAsync(alreadyExistsUserContact))
            .ThrowsAsync(duplicateKeyException);

            // when
            ValueTask <UserContact> addUserContactTask =
                this.userContactService.AddUserContactAsync(alreadyExistsUserContact);

            // then
            await Assert.ThrowsAsync <UserContactValidationException>(() =>
                                                                      addUserContactTask.AsTask());

            this.loggingBrokerMock.Verify(broker =>
                                          broker.LogError(It.Is(SameExceptionAs(
                                                                    expectedUserContactValidationException))),
                                          Times.Once);

            this.storageBrokerMock.Verify(broker =>
                                          broker.InsertUserContactAsync(alreadyExistsUserContact),
                                          Times.Once);

            this.loggingBrokerMock.VerifyNoOtherCalls();
            this.storageBrokerMock.VerifyNoOtherCalls();
        }