上层模块调用底层模块的接口,返回错误代码的时候,如果采用这种方式:
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;
}