/// <summary>
 /// Initializes a new instance of the <see cref="BaseException" /> class. This is used internally for restoring exception instance from ExceptionInfo.
 /// </summary>
 /// <param name="key">The key.</param>
 /// <param name="createdStamp">The created stamp.</param>
 /// <param name="message">The message.</param>
 /// <param name="scene">The scene.</param>
 /// <param name="code">The code.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="operatorCredential">The operator credential.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 protected BaseException(Guid key, DateTime createdStamp, string message, ExceptionScene scene, ExceptionCode code, Exception innerException, BaseCredential operatorCredential, JToken data, FriendlyHint hint)
     : base(message, innerException)
 {
     this.Key = key;
     this.CreatedStamp = createdStamp;
     this.Scene = scene;
     this.Code = code;
     this.OperatorCredential = operatorCredential as BaseCredential;
     this.ReferenceData = data;
     this.Hint = hint;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseException" /> class.
        /// </summary>
        /// <param name="message">The exception message.</param>
        /// <param name="code">The exception code.</param>
        /// <param name="innerException">The inner exception.</param>
        /// <param name="data">The data.</param>
        /// <param name="hint">The hint.</param>
        /// <param name="scene">The scene.</param>
        protected BaseException(string message, ExceptionCode code, Exception innerException = null, object data = null, FriendlyHint hint = null, ExceptionScene scene = null)
            : base(message, innerException)
        {
            this.Code = code;
            this.OperatorCredential = ContextHelper.CurrentCredential;
            this.ReferenceData = data == null ? null : JToken.FromObject(data);
            this.Scene = scene;
            this.CreatedStamp = DateTime.UtcNow;

            var inner = innerException as BaseException;
            this.Key = inner == null ? Guid.NewGuid() : inner.Key;
            this.Hint = hint ?? inner?.Hint;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ResourceNotFoundException" /> class.
 /// </summary>
 /// <param name="key">The key.</param>
 /// <param name="createdStamp">The created stamp.</param>
 /// <param name="message">The message.</param>
 /// <param name="scene">The scene.</param>
 /// <param name="code">The code.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="operatorCredential">The operator credential.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 internal ResourceNotFoundException(Guid key, DateTime createdStamp, string message, ExceptionScene scene, ExceptionCode code, Exception innerException, BaseCredential operatorCredential, JToken data, FriendlyHint hint)
     : base(key, createdStamp, message, scene, code, innerException, operatorCredential, data, hint)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="InitializationFailureException" /> class.
 /// </summary>
 /// <param name="target">The object identity.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="minor">The minor.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="scene">The scene.</param>
 public InitializationFailureException(string target, Exception innerException = null, string minor = null, object data = null, FriendlyHint hint = null, ExceptionScene scene = null)
     : base(string.Format("Failed to initialize [{0}].", target), new ExceptionCode { Major = ExceptionCode.MajorCode.ServiceUnavailable, Minor = minor.SafeToString("Initialize") }, innerException, data, hint, scene)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="UnauthorizedOperationException" /> class.
 /// </summary>
 /// <param name="reason">The reason.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="operationName">Name of the operation.</param>
 public UnauthorizedOperationException(string reason = null, object data = null, FriendlyHint hint = null, [CallerMemberName] string operationName = null)
     : base(string.Format("Unauthorized action on [{0}].", operationName),
                new ExceptionCode { Major = ExceptionCode.MajorCode.UnauthorizedOperation, Minor = reason.SafeToString("Operation") }, data: data, hint: hint)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="UnauthorizedOperationException" /> class.
 /// </summary>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="reason">The minor code.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="scene">The scene.</param>
 public UnauthorizedOperationException(Exception innerException = null, string reason = null, object data = null, FriendlyHint hint = null, ExceptionScene scene = null)
     : base(string.Format("Unauthorized action on [{0}].", scene?.MethodName),
           new ExceptionCode { Major = ExceptionCode.MajorCode.UnauthorizedOperation, Minor = reason.SafeToString("Operation") }, innerException, data, hint, scene)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="OperationFailureException" /> class.
 /// </summary>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="data">The data.</param>
 /// <param name="minor">The minor.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="scene">The scene.</param>
 public OperationFailureException(Exception innerException = null, object data = null, string minor = null, FriendlyHint hint = null, ExceptionScene scene = null)
     : base(string.Format("Failed to operate to [{0}].", scene?.MethodName), new ExceptionCode { Major = ExceptionCode.MajorCode.OperationFailure, Minor = minor }, innerException, data, hint, scene)
 {
 }
        /// <summary>
        /// Handles the exception.
        /// </summary>
        /// <param name="exception">The exception.</param>
        /// <param name="scene">The scene.</param>
        /// <param name="data">The data.</param>
        /// <param name="hint">The hint.</param>
        /// <returns>BaseServiceException.</returns>
        public static BaseException Handle(this Exception exception, ExceptionScene scene, object data = null, FriendlyHint hint = null)
        {
            TargetInvocationException targetInvocationException = exception as TargetInvocationException;

            if (targetInvocationException != null)
            {
                return targetInvocationException.InnerException.Handle(scene, data, hint);
            }
            else
            {
                var baseException = exception as BaseException;
                var operationName = scene?.MethodName;

                if (baseException != null)
                {
                    if (string.IsNullOrWhiteSpace(operationName))
                    {
                        return baseException;
                    }
                    else
                    {
                        switch (baseException.Code.Major)
                        {
                            case ExceptionCode.MajorCode.UnauthorizedOperation:
                                return new UnauthorizedOperationException(baseException, baseException.Code.Minor, data, scene: scene) as BaseException;
                            case ExceptionCode.MajorCode.OperationForbidden:
                                return new OperationForbiddenException(operationName, baseException.Code?.Minor, baseException, data, scene: scene) as BaseException;
                            case ExceptionCode.MajorCode.NullOrInvalidValue:
                            case ExceptionCode.MajorCode.DataConflict:
                            case ExceptionCode.MajorCode.NotImplemented:
                            case ExceptionCode.MajorCode.ResourceNotFound:
                            case ExceptionCode.MajorCode.CreditNotAfford:
                            case ExceptionCode.MajorCode.ServiceUnavailable:
                                return baseException;
                            default:
                                break;
                        }
                    }
                }
                else
                {
                    var sqlException = exception as SqlException;

                    if (sqlException != null)
                    {
                        return new OperationFailureException(exception, data, hint: hint, scene: scene) as BaseException;
                    }
                    else
                    {
                        var notImplementException = exception as NotImplementedException;

                        if (notImplementException != null)
                        {
                            return new UnimplementedException(operationName, notImplementException);
                        }
                    }
                }

                return new OperationFailureException(exception, data, scene: scene) as BaseException;
            }
        }
 /// <summary>
 /// Handles the specified exception.
 /// </summary>
 /// <param name="exception">The exception.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="operationName">Name of the operation.</param>
 /// <param name="sourceFilePath">The source file path.</param>
 /// <param name="sourceLineNumber">The source line number.</param>
 /// <returns>Beyova.ExceptionSystem.BaseException.</returns>
 public static BaseException Handle(this Exception exception, object data = null, FriendlyHint hint = null,
             [CallerMemberName] string operationName = null,
             [CallerFilePath] string sourceFilePath = null,
             [CallerLineNumber] int sourceLineNumber = 0)
 {
     return Handle(exception, new ExceptionScene
     {
         MethodName = operationName,
         FilePath = sourceFilePath,
         LineNumber = sourceLineNumber
     }, data, hint);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="InvalidObjectException" /> class.
 /// </summary>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="data">The data.</param>
 /// <param name="reason">The reason.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="scene">The scene.</param>
 internal InvalidObjectException(Exception innerException, object data = null, string reason = null, FriendlyHint hint = null, ExceptionScene scene = null)
     : base((innerException?.Message).SafeToString("Invalid object."), new ExceptionCode { Major = ExceptionCode.MajorCode.NullOrInvalidValue, Minor = reason.SafeToString("InvalidObject") }, innerException, data, hint, scene)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="InvalidObjectException" /> class.
 /// </summary>
 /// <param name="objectIdentity">The object identity.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="data">The data.</param>
 /// <param name="reason">The reason.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="scene">The scene.</param>
 public InvalidObjectException(string objectIdentity, Exception innerException = null, object data = null, string reason = null, FriendlyHint hint = null, ExceptionScene scene = null)
     : base(string.Format("Object [{0}] is invalid.", objectIdentity), new ExceptionCode { Major = ExceptionCode.MajorCode.NullOrInvalidValue, Minor = reason.SafeToString("InvalidObject") }, innerException, data, hint, scene)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="UnsupportedException" /> class.
 /// </summary>
 /// <param name="objectIdentifier">The object identifier.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="reason">The reason.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="scene">The scene.</param>
 public UnsupportedException(string objectIdentifier, Exception innerException = null, string reason = null, object data = null, FriendlyHint hint = null, ExceptionScene scene = null)
     : base(string.Format("[{0}] is not supported .", objectIdentifier), new ExceptionCode { Major = ExceptionCode.MajorCode.CreditNotAfford, Minor = reason }, innerException, data, hint, scene)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="OperationForbiddenException"/> class.
 /// </summary>
 /// <param name="reason">The reason.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="actionName">Name of the action.</param>
 public OperationForbiddenException(string reason, Exception innerException = null, object data = null, FriendlyHint hint = null, [CallerMemberName] string actionName = null)
     : base(string.Format("Operation [{0}] is forbidden. Reason: {1}", actionName, reason), new ExceptionCode { Major = ExceptionCode.MajorCode.OperationForbidden, Minor = reason }, innerException, data, hint, null)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="DataConflictException" /> class.
 /// </summary>
 /// <param name="entityName">Name of the entity.</param>
 /// <param name="objectIdentity">The object identity.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="scene">The scene.</param>
 public DataConflictException(string entityName, string objectIdentity = null, Exception innerException = null, object data = null, FriendlyHint hint = null, ExceptionScene scene = null)
     : base(string.Format("Data conflicts for [{0}] at [{1}]", entityName, objectIdentity), new ExceptionCode { Major = ExceptionCode.MajorCode.DataConflict, Minor = entityName }, innerException, data, hint, scene)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="CreditNotAffordException" /> class.
 /// </summary>
 /// <param name="resourceName">Name of the resource.</param>
 /// <param name="resourceIdentifier">The resource identifier.</param>
 /// <param name="innerException">The inner exception.</param>
 /// <param name="minor">The minor.</param>
 /// <param name="data">The data.</param>
 /// <param name="hint">The hint.</param>
 /// <param name="scene">The scene.</param>
 public CreditNotAffordException(string resourceName, string resourceIdentifier, Exception innerException = null, string minor = null, object data = null, FriendlyHint hint = null, ExceptionScene scene = null)
     : base(string.Format("Credit is not afford for resource [{0}] at [{1}].", resourceName, resourceIdentifier), new ExceptionCode { Major = ExceptionCode.MajorCode.CreditNotAfford, Minor = minor.SafeToString(resourceName) }, innerException, data, hint, scene)
 {
 }