none
SqlClient Exception 的疑問 RRS feed

  • 問題

  • 程式碼結構如下:

            /// <summary>
            /// 將Msg寫入DB,
            /// </summary>
            /// <param name="msg">訊息</param>
            public void WriteMessageToDB(string msg, string logpath)
            {
                try
                {
                    conn.Open();
                    SqlCommand cmd = new SqlCommand("Insert into InvoiceUploadMailLog values(@Msg,DEFAULT,@Update,DEFAULT)", conn);
                    SqlParameter MsgPara = new SqlParameter("@Msg", SqlDbType.NVarChar);
                    SqlParameter UpdatePara = new SqlParameter("@Update", (object)DBNull.Value);
                    MsgPara.Value = msg;
                    cmd.Parameters.Add(MsgPara);
                    cmd.Parameters.Add(UpdatePara);
                    cmd.ExecuteNonQuery();
                }
                catch (SqlException se)
                {
                    throw new Exception("test");
                }
                catch (Exception ex)
                {
                    throw new Exception("WriteMessageToDB 發生未知錯誤," + ex.Message);
                }
                finally
                {
                    conn.Close();
                }
                
            }

    try
    {
                            try
                        {
                            fc.WriteMessageToDB(Global.ErrorMsg.ToString(),LogPath);
                            fc.WriteMessageToLog("DB寫入成功", LogPath);
                        }
                        catch (Exception ex)
                        {
                            fc.WriteMessageToLog(ex.Message, LogPath);
                            Global.ErrorMsg.Append(fc.AppendErrorMsg("寫入資料庫失敗"));
                            fc.SendEmail(Global.ErrorMsg.ToString(), LogPath);
                        }
    }
    catch(Exception)
    {
       .....
    }

    疑問是,我跑了之後 WriteMessageToDB 出現SqlClient Expcetion,照道理throw出去,應該是內層的 Exception會處理吧,為什麼我測試他會一直跑到外層去??

    2012年2月14日 上午 06:08

解答

  • 我用下列程式碼模擬你的問題,不曉得有沒有會錯你的意思,但執行順序會是先印出sqlexception,再印出內圈的exception。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Data.SqlClient;
    
    namespace WebApplication2
    {
        public partial class ErrorHandle : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                try
                {
                    try
                    {
                        WriteMessageToDB(string.Empty, string.Empty);
                    }
                    catch (Exception ex)
                    {
                        Response.Write("內圈Exception<br/>");
                    }
                }
                catch (Exception ex)
                {
                    Response.Write("外圈Exception<br/>");
                }
            }
    
            private void WriteMessageToDB(string msg, string logpath)
            {
                try
                {
                    SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
                    builder.DataSource = ".";
                    builder.InitialCatalog = "Northwind1";
                    builder.IntegratedSecurity = true;
                    using (SqlConnection con = new SqlConnection(builder.ToString()))
                    {
                        con.Open();
                    }
    
                }
                catch (SqlException se)
                {
                    Response.Write("SqlException<br/>");
                    throw se;
                }
                catch (Exception ex)
                {
                    Response.Write("Exception<br/>");
                    throw ex;
                }
            }
        }
    }


    以上說明若有錯誤請指教,謝謝。
    http://www.dotblogs.com.tw/terrychuang/

    • 已標示為解答 GragonP 2012年2月14日 下午 01:37
    2012年2月14日 下午 12:10

所有回覆

  • 請問您是說,它沒有跑到 test這個Exception嗎? 還是??

    SqlException

    =>throw new Exception("test");

    =>外層 catch


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/


    • 已編輯 亂馬客 2012年2月14日 上午 06:39
    2012年2月14日 上午 06:36
  • 是跑到test 那個Exception,不過他是throw 到他上一層包的

    也就是第二個程式碼所寫的 

    先用一try catch(Exception裡面是...這個) 包在最外面

    裡面再用一個try catch(Exception ex 這個) 

    在裡面才去呼叫我第一個程式碼所寫的function

    那照理是會丟回上一層  也就是(Exception ex這個會接住吧)

    2012年2月14日 上午 09:47
  • 用圖比較好看,應該會像下圖這樣的走法吧!

    您Trace出來的走法有不同嗎?

    如果會走到catch(Exception)的話,表示上圖標2的Exception處理有發生錯誤,才會throw Exception.


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/


    • 已編輯 亂馬客 2012年2月14日 上午 10:45
    2012年2月14日 上午 10:44
  • 我用下列程式碼模擬你的問題,不曉得有沒有會錯你的意思,但執行順序會是先印出sqlexception,再印出內圈的exception。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Data.SqlClient;
    
    namespace WebApplication2
    {
        public partial class ErrorHandle : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                try
                {
                    try
                    {
                        WriteMessageToDB(string.Empty, string.Empty);
                    }
                    catch (Exception ex)
                    {
                        Response.Write("內圈Exception<br/>");
                    }
                }
                catch (Exception ex)
                {
                    Response.Write("外圈Exception<br/>");
                }
            }
    
            private void WriteMessageToDB(string msg, string logpath)
            {
                try
                {
                    SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
                    builder.DataSource = ".";
                    builder.InitialCatalog = "Northwind1";
                    builder.IntegratedSecurity = true;
                    using (SqlConnection con = new SqlConnection(builder.ToString()))
                    {
                        con.Open();
                    }
    
                }
                catch (SqlException se)
                {
                    Response.Write("SqlException<br/>");
                    throw se;
                }
                catch (Exception ex)
                {
                    Response.Write("Exception<br/>");
                    throw ex;
                }
            }
        }
    }


    以上說明若有錯誤請指教,謝謝。
    http://www.dotblogs.com.tw/terrychuang/

    • 已標示為解答 GragonP 2012年2月14日 下午 01:37
    2012年2月14日 下午 12:10
  • T大的意思就跟我一樣,不過如果se拋出例外,內圈的Exception那個會不會接續下去,因為我測的時候都不行 …還是我有地方寫錯了
    2012年2月14日 下午 12:59
  • T大的意思就跟我一樣,不過如果se拋出例外,內圈的Exception那個會不會接續下去,因為我測的時候都不行 …還是我有地方寫錯了
    或許你先用個簡單的專案來測試看看,會比較容易找到問題點。

    以上說明若有錯誤請指教,謝謝。
    http://www.dotblogs.com.tw/terrychuang/

    2012年2月14日 下午 01:04
  • 感謝,測試完畢,那我在調整一下我的就好了  謝囉
    2012年2月14日 下午 01:37