private FaultException GetFault(Exception e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }
            if (e is PreConditionNotFulfilledException)
            {
                return(PreConditionNotFulfilledFault.GetFault(e));
            }
            if (e is InvalidStateTransitionException)
            {
                return(InvalidStateTransitionFault.GetFault(e));
            }
            if (e is COMException)
            {
                return(ApiFault.GetFault(e as COMException));
            }
            if (e is UpdateNotFoundException)
            {
                return(UpdateNotFoundFault.GetFault(e, ((UpdateNotFoundException)e).UpdateId));
            }
            //if (e is ArgumentOutOfRangeException) return BadArgumentFault.GetFault(e as ArgumentOutOfRangeException);
            if (e is ArgumentException)
            {
                return(BadArgumentFault.GetFault(e as ArgumentException));
            }

            // Other exceptions should never happen. Do not wrap them in to faults.
            Log.Error("An unexpected expection was thrown.", e);
            ExceptionDispatchInfo.Capture(e).Throw(); // Keep the stack trace and rethrow
            throw new NotImplementedException($"Avoid compiler error. Should never be reached, because {nameof(ExceptionDispatchInfo)} rethrows the exception. But the compiler does not know that.");
        }
        public void Should_ContainExpectedFaultCode_When_CreateFault()
        {
            Exception         ex  = new Exception();
            ArgumentException aex = new ArgumentException();
            var comex             = new COMException();

            var fault1 = InvalidStateTransitionFault.GetFault(ex);
            var fault2 = PreConditionNotFulfilledFault.GetFault(ex);
            var fault3 = BadArgumentFault.GetFault(aex);
            var fault4 = ApiFault.GetFault(comex);
            var fault5 = UpdateNotFoundFault.GetFault(ex, "update1");

            Assert.AreEqual(fault1.Code.Name, "InvalidTransition");
            Assert.AreEqual(fault2.Code.Name, "PreConditionNotFulfilled");
            Assert.AreEqual(fault3.Code.Name, "BadArgument");
            Assert.AreEqual(fault4.Code.Name, "ApiFault");
            Assert.AreEqual(fault5.Code.Name, "UpdateNotFound");
        }
        public void Should_ContainExceptionMessage_When_CreateFault()
        {
            string            message = "UnitTest";
            Exception         ex      = new Exception(message);
            ArgumentException aex     = new ArgumentException(message);
            var comex = new COMException(message);

            var fault1 = InvalidStateTransitionFault.GetFault(ex);
            var fault2 = PreConditionNotFulfilledFault.GetFault(ex);
            var fault3 = BadArgumentFault.GetFault(aex);
            var fault4 = ApiFault.GetFault(comex);
            var fault5 = UpdateNotFoundFault.GetFault(ex, "update1");

            Assert.AreEqual(fault1.Message, message);
            Assert.AreEqual(fault2.Message, message);
            Assert.AreEqual(fault3.Message, message);
            Assert.AreEqual(fault4.Message, message);
            Assert.AreEqual(fault5.Message, message);

            var fault9 = new TestFault(new Exception(message));

            Assert.AreEqual(fault9.Message, message);
        }