包含信息栈的Error传递

上层模块调用底层模块的接口,返回错误代码的时候,如果采用这种方式:

        public const int ERR_0 = 0;
        public const int ERR_1 = 1;
        public class ShellExcuteResult
        {
            public int Code { get; set; }
            public string Output { get; set; }
            public string Error { get; set; }
        }
        static ShellExcuteResult shellExcute_0()
        {
            ShellExcuteResult result = new ShellExcuteResult();
            result.Code = ERR_1;
            result.Output = "Success";
            result.Error = "pkg 6kb/s";
            return result;
        }

        public const int INSTALL_SUCCESS = 0;
        public const int INSTALL_FAIL = 1;
        static int install_0()
        {
            ShellExcuteResult result = shellExcute_0();
            if (result.Code == ERR_0)
            {
                return INSTALL_SUCCESS;
            }
            else
            {
                return INSTALL_FAIL;
            }
        }

将造成了信息的丢失,调用install接口的只知道安装成功或者失败,而无法得到失败的原因。也正是因为如此,要写LOG的时候会非常麻烦,因为往往是在上层模块的接口调用失败的时候需要写LOG,但是在失败的地方,却得不到足够的信息,只能在底层也写LOG。

一个合适的做法是,像Exception的栈一样,为Error带上信息栈。

    abstract class LxError
    {
        private LxError mInnerError;
        public LxError()
            : this(null)
        {
        }
        public LxError(LxError innerError)
        {
            mInnerError = innerError;
        }
        public abstract Object Data { get; }
        public LxError InnerError { get { return mInnerError; } }
        public string Source { get; set; }
        public string Message(string prefix)
        {
            return RMessage("", prefix);
        }
        protected string RMessage(string prefix1, string prefix2)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(this.MessageString(prefix1));
            if (mInnerError != null)
            {
                stringBuilder.Append("\n");
                stringBuilder.Append(mInnerError.RMessage(prefix1 + prefix2, prefix2));
            }
            return stringBuilder.ToString();
        }
        public abstract string MessageString(string prefix);
        protected StringBuilder BaseMessageStringBuilder(string prefix)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(prefix).Append("Source : ").Append("\"").Append(Source).Append("\"").Append("\n");
            stringBuilder.Append(prefix).Append("Data : ");
            return stringBuilder;
        }
    }

    class ShellError : LxError
    {
        private Dictionary<string, object> mData = new Dictionary<string, object>();
        public override object Data
        {
            get
            {
                return mData;
            }
        }
        public override string MessageString(string prefix)
        {
            StringBuilder stringBuilder = BaseMessageStringBuilder(prefix);
            if (mData.Count == 0)
            {
                stringBuilder.Append("empty");
            }
            else
            {
                Dictionary<string, object>.KeyCollection keys = mData.Keys;
                foreach (string key in keys)
                {
                    stringBuilder.Append("[").Append(key).Append(":").Append(mData[key]).Append("]");
                }
            }
            return stringBuilder.ToString();
        }
    }

    class InstallError : LxError
    {
        public const int INSTALL_SUCCESS = 0;
        public const int INSTALL_FAIL = 1;
        public const string INSTALL_SUCCESS_STR = "INSTALL_SUCCESS";
        public const string INSTALL_FAIL_STR = "INSTALL_FAIL";

        public InstallError(ShellError shellError)
            : base(shellError)
        {
            if ((int)((IDictionary)shellError.Data)["code"] == 0)
            {
                mData = INSTALL_SUCCESS;
            }
            else
            {
                mData = INSTALL_FAIL;
            }

        }
        private int mData;
        public override object Data
        {
            get
            {
                return mData;
            }
        }
        public override string MessageString(string prefix)
        {
            StringBuilder stringBuilder = BaseMessageStringBuilder(prefix);
            stringBuilder.Append(mData == INSTALL_SUCCESS ? INSTALL_SUCCESS_STR : INSTALL_FAIL_STR);
            return stringBuilder.ToString();
        }
    }

        static ShellError shellExcute()
        {
            ShellError error = new ShellError();
            ((IDictionary)error.Data)["code"] = 1;
            ((IDictionary)error.Data)["output"] = "Success";
            ((IDictionary)error.Data)["error"] = "pkg 6kb/s";
            error.Source = "Program : shellExcute";
            return error;
        }

        static InstallError install()
        {
            ShellError shellError = shellExcute();
            InstallError error = new InstallError(shellError);
            error.Source = "Program : install";
            return error;
        }
原文地址:https://www.cnblogs.com/zhengwenwei/p/2244737.html