dotnet中的錯誤處理

來源:互聯網
上載者:User
近日給老美做外包項目,被老美逼出來了一套關於錯誤處理的方法,在此不敢藏拙,奉獻出來給大家批判。

首先,屏蔽程式中所有的自動錯誤處理,千萬不要出來:“
System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: 伺服器無法處理請求。”等錯誤頁面,而應該是一些簡單易懂的東西,俺在此使用的是Duwamish 7.0裡的錯誤處理頁面:
<body >
           <H2>An error has occurred</H2>
           <P>We were unable to complete your request. This failure has been logged with our
                 system administrators, who are currently working to resolve the problem. We
                 apologize for any inconvenience caused by this temporary service outage, and we
                 appreciate your patience as we work to improve our web site.</P>
     </body>
當然,要做到這一點也很簡單,可以在web.config裡這樣配置(假如你的錯誤頁面叫Error.aspx):
 <customErrors
    defaultRedirect = "Error.aspx"
    mode="On"
    />
這個配置你可以給據你的需要修改(比如mode的值)。

其次,要把錯誤資訊寫到日誌中去。
我們定義錯誤記錄檔資訊的結構如下
public struct ErrorLogItem
     {
        public string User ;//當前登入人
           public string AppName ;//應用程式名稱
           public string ClassName ;//錯誤發生的類名稱
           public string FunctionName ;//錯誤發生的方法(事件)名稱
           public string Position ;//錯誤的位置(或其它資訊)
           public string ErrorInfo ;//錯誤資訊
           public DateTime OccurTime ;//錯誤發生的時間
     }

錯誤記錄檔類如下所示:
public class ErrorLog
     {
           private static ErrorLog _Instance = null ;
           private static string strRootName  ;
           private static XmlElement xmlRoot ;
           private static XmlDocument xmlDoc ;
           private ErrorLog()
           {
                 Load() ;
           }
           private bool Load()
           {
                 if (!File.Exists(AppGlobal.ErrorLogFile))
                       CreateErrorLogFile(AppGlobal.ErrorLogFile);
                 
                 if (xmlDoc == null)
                       xmlDoc = new XmlDocument() ;      
                 try
                 {
                       xmlDoc.Load(AppGlobal.ErrorLogFile) ;
                 }
                 catch
                 {
                       return false ;
                 }
                 xmlRoot = xmlDoc.DocumentElement ;
                 if (xmlRoot != null)
                       strRootName = "/" + xmlRoot.Name + "/" ;
                 return true ;
           }
           private void CreateErrorLogFile(string strFileName)
           {                  
                 StringBuilder sb = new StringBuilder() ;
                 sb.Append("<?xml version='1.0/' ?> ") ;
                 sb.Append("<errorlog>") ;
                 sb.Append("</errorlog>") ;
 
                 XmlDocument xmlDoc = new XmlDocument() ;
                 xmlDoc.LoadXml(sb.ToString()) ;
                 xmlDoc.Save(strFileName) ;            
           }
           private void AddXmlAttribute(XmlElement xNode,string strAttr,string strAttrvalue)
           {
                 XmlAttribute xAttr = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute,strAttr,null) ;
                 xAttr.InnerText = strAttrvalue;
                 xNode.Attributes.Append(xAttr) ;
           }
           public void SetErrorLog(ErrorLogItem errItem)
           {
                 XmlElement xErrorElement = xmlDoc.CreateElement("error") ;

                 AddXmlAttribute(xErrorElement,"username",errItem.User);
                 AddXmlAttribute(xErrorElement,"application",errItem.AppName);
                 AddXmlAttribute(xErrorElement,"classname",errItem.ClassName);
                 AddXmlAttribute(xErrorElement,"functionname",errItem.FunctionName);
                 AddXmlAttribute(xErrorElement,"position",errItem.Position);
                 AddXmlAttribute(xErrorElement,"occurtime",errItem.OccurTime.ToString("g"));
                 xErrorElement.InnerText = errItem.ErrorInfo ;

                 xmlRoot.AppendChild(xErrorElement) ;
           
                 if (xmlRoot.ChildNodes.Count > AppGlobal.MaxErrorLogCount)
                       xmlRoot.RemoveChild(xmlRoot.FirstChild) ;
                 xmlDoc.Save(AppGlobal.ErrorLogFile) ;
           }
           
           public static ErrorLog Instance()
           {
                 if(_Instance == null)
                 {
                       _Instance = new ErrorLog() ;
                 }
                 return _Instance ;
           }
     }//end class      

我們可以通過調用SetErrorLog方法來把資訊寫到日誌中去。
當然,日誌的位置以及日誌記錄錯誤資訊的數量也是可以配置的
<appSettings>
           <add key="errlogfile" value="c:/ddmsLog.xml" />
           <add key="maxerrlogcount" value="1000" />
</appSettings>
我們可以通過下面的方法得到他們的值:
public static string ErrorLogFile
           {
                 get
                 {
                       return ConfigurationSettings.AppSettings["errlogfile"].Trim() ;
                 }
           }
           public static int MaxErrorLogCount
           {
                 get
                 {
                       return int.Parse(ConfigurationSettings.AppSettings["maxerrlogcount"].Trim()) ;
                 }
           }

再次,我們還要把錯誤資訊自動發到我們的信箱中(這一點很重要--至少對我這個項目來說,我不能跑到美國去調試,也不能老是讓老外告訴我發生了什麼錯誤)
發送郵件的方法如下:
public static bool SendErrorLogMail(string StrTo,ErrorLogItem errItem)
           {
                 MailLink.Load(AppGlobal.MAIL_CFG_FILE_PATH) ;

                 string StrName = MailLink.GetNodeText(MAILLINKITEM.USERNAME) ;
                 string StrCode = MailLink.GetNodeText(MAILLINKITEM.PASSWORD) ;
                 
                 string strFrom =   MailLink.GetNodeText(MAILLINKITEM.MAILFROM) ;
                 string strSubject = "Error Log" ;
                 string strSmtpServer = MailLink.GetNodeText(MAILLINKITEM.MAILSMTPSERVER) ;
                 
                 string strMailBody = "<div>An error occur </div>" ;
                 strMailBody += "<div>Login User:" + errItem.User + "</div>" ;
                 strMailBody += "<div>Applicatin Name:" + errItem.AppName + "</div>" ;
                 strMailBody += "<div>ClassName:" + errItem.ClassName + "</div>" ;
                 strMailBody += "<div>Function Name:" + errItem.FunctionName + "</div>" ;                  
                 strMailBody += "<div>Error Position:" + errItem.Position + "</div>" ;
                 strMailBody += "<div>Error Information:" + errItem.ErrorInfo + "</div>" ;                  
                 strMailBody += "<DIV> </DIV>" ;
                 strMailBody += "<DIV> </DIV>" ;
                 strMailBody += "<DIV>" + errItem.OccurTime + "</DIV>" ;

                 bool blResult = MailLink.SendMail(StrTo,strMailBody,strSubject,strFrom,StrName,StrCode,strSmtpServer) ;

                 return blResult ;
           }      
意思大家應該明白,裡面具體的一些方法調用大家可以寫自己的代碼來代替。
當然,郵箱地址也是可以配置的:
<appSettings>
           <add key="errorlogemail" value="zl3624@china.com" />
</appSettings>
取出方法:
public static string ErrorLogEmail
           {
                 get
                 {
                       return ConfigurationSettings.AppSettings["errorlogemail"].Trim() ;
                 }
           }
最後,是用一個方法來調用寫日誌和發郵件的方法:
public static void LogAppError(Exception thisErr,string strClass,string strFunc,string strPos,string strUser)
           {                  
                 ErrorLogItem errItem = new ErrorLogItem() ;
                       
                 errItem.AppName = "Your AppName" ;
                 errItem.ClassName = strClass ;
                 errItem.ErrorInfo = thisErr.ToString() ;
                 errItem.FunctionName = strFunc ;
                 errItem.OccurTime = DateTime.Now ;
                 errItem.Position = strPos ;
                 errItem.User =strUser ;

                 try
                 {
                       ErrorLog.Instance().SetErrorLog(errItem) ;
                       SendErrorLogMail(ErrorLogEmail,sb.ToString()) ;
                 }
                 catch
                 {
                 }
                 finally
                 {
                       
                 }
                 throw new Exception("An error occur :"+thisErr.ToString()) ;
}
那麼,怎樣在程式中捕獲異常哪?
下面是俺的一段代碼:
public DataSet GetPrsnInfo(int aiTrx_no,int aiIncid_no,int aiPrsn_id)
           {
                 try
                 {
                       ddmsWsPInfo.CandiService ddmsCS =  new ddmsWsPInfo.CandiService() ;
                       ddmsCS.Url = AppGlobal.WebServicesUrl ;
                       DataSet dsPrsn = ddmsCS.GetPrsnInfo(aiTrx_no,aiIncid_no,aiPrsn_id) ;
                       ddmsCS.Dispose();
                       return dsPrsn ;
                 
                 }
                 catch(Exception e)
                 {
                       string strErr = "aiTrx_no=" + aiTrx_no +  " aiIncid_no=" + aiIncid_no +  " aiPrsn_id=" + aiPrsn_id ;
                       AppGlobal.LogAppError(e,"PrsnManager","GetExtraPrsn",strErr,LoginUser.UserID) ;
                       return null ;
                 }      
           }

呵呵,這樣錯誤處理應該差不多了吧?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.