在cs分层系统中,我是在ui层处理异常的。
ui层
try
{
  BLL.TrailerJob.Consign.DeleteConsign(_ConsignID);
}
catch (Exception ex)
{
  MessageBox.Show(ex.Message.ToString());
}
sql层 public DataTable FillCargoType(string pSearch)
        {
            DataTable dt = null;
            string conditon = "";
            if (pSearch != "")
            {
                conditon = " WHERE CargoType LIKE '%" + pSearch.Replace("'", "''") + "%' OR Cargo LIKE '%" + pSearch.Replace("'", "''") + "%'";
            }
            string str_SQL = " SELECT [CargoTypeID], [CargoType] AS 货类, [Cargo] AS 货物 " +
                             " FROM [TM_CargoType]" + conditon + " ORDER BY CargoTypeID DESC ";
            try
            {
                dt = SQLHelper.ExecuteDataTable(SQLHelper.SQLHelper_SqlConn, str_SQL);
            }
            catch
            {
                throw;
            }
            return dt;
        }问题1.既然在ui层捕获了异常,那sql层的throw异常是否可以不需要了?去掉了好像也没大的关系。
问题2.觉得这样处理异常不好,高手帮我指点下迷津,是否该用自定义异常,自定义异常的意义和处理方法(最好有代码)。

解决方案 »

  1.   

    问题1.既然在ui层捕获了异常,那sql层的throw异常是否可以不需要了?去掉了好像也没大的关系。 
    --- 如果采用了自定义的异常,这里就不一样了,
    可以 
    throw new ApplicationExcetion("自定义异常消息string");问题2.觉得这样处理异常不好,高手帮我指点下迷津,是否该用自定义异常,自定义异常的意义和处理方法(最好有代码)。
    ---
    class MyException : Exception
    {
      // 和定义 普通的类 没有什么区别。
    }
      

  2.   

    自定义异常可以使出错信息更友好些,比如抛出的SqlException为主键冲突,你可以自己封装成自定义异常,比如提示该xx已存在,然后抛出给UI捕获。
    对于不可预料的直接封装为未知异常,因为用户不可能理解异常信息的含义。但是在程序内部有必要log异常信息。
      

  3.   

    throw new ApplicationExcetion("自定义异常消息string"); 
    一般只要用一个这个就可以抛出!
      

  4.   

    问题一:
      不可以删除sql层的throw异常,否则SQL层的异常无法捕捉会导致程序中断。
    问题二:
      各人觉得不需要使用自定义异常,异常本身没有任何业务意义,花费太多精力设计没必要,一个好的设计应当避免产生异常的程序路径,而像网络连接中断这样的环境异常语言都有了。
      

  5.   

    高手帮我解释下这个是怎么执行的.
    ui层调用
      疑问: throw new BLLException(0xFFFE);为什么可以弹出"页面过期,请重新登录系统!"的错误提示?不明白。只是传入了0xFFFE,并没有方法把0xFFFE与"页面过期,请重新登录系统!"的错误提示关联起来啊?
    BLLException类的定义
    /// <summary>
    /// Exception throw out from business logical layer。
    /// </summary>
    public class BLLException : ERPException
    {
    public BLLException() : base() { } public BLLException(int number) : base(number) {} public BLLException(string message) : base(message) {}
    }
    ERPException 的定义
    public class ERPException : Exception
    {
    private int _errNumber; public ERPException() : base()
    {
    this._errNumber = 0x0000;
    } public ERPException(int errNumber) : base()
    {
    this._errNumber = errNumber;
    } public ERPException(string message) : base()
    {
    //this._errNumber = XResource.ResourceFactory.SetMessage(message);
    } public int ErrorNumber
    {
    get { return this._errNumber; }
    } public override string Message
    {
    get { return DefaultVersion.GetMessage(_errNumber); }
    }
    }
    DefaultVersion 的定义
    public class DefaultVersion 
    {
    public DefaultVersion()
    {
    } public static string GetMessage(int number)
    {
    switch( number )
    {
    // User relative messages
    case 0x0000: return ""; //"系统运行正常。";
    case 0xFFFE: return "您没有进行当前操作的权限!";
    case 0xFFFF: return "页面过期,请重新登录系统!"; // Default
    default: return "未知错误!";
    }
    }
    }
      

  6.   

    你好,不能保证一定是在UI层抛出的啊 是什么意思?
    我是ui待遇bll,bll调sql,sql抛出异常,在ui一定可以捕获啊,或者去掉ui捕获,直接在sql throw?
      

  7.   

    ui层
    try
    {
      BLL.TrailerJob.Consign.DeleteConsign(_ConsignID);
    }
    catch (ExceptionWeb ex) // ExceptionWeb自定义 Exception
    {
      MessageBox.Show(ex.Message);
    }
    catch (Exception ex) // ExceptionWeb自定义 Exception
    {
      Log.Append(ex); // 记录错误日志
      MessageBox.Show("发生错误");
    }
      

  8.   

    你好,请问发生异常,怎么就会自动跑到ExceptionWeb异常中,如果不能捕获,那也就不能记录错误日志了啊。
    就是系统怎么判断这个异常属于自定义异常。
      

  9.   


    个人觉得,你在处理SQL语句时,有可能捕获到异常,这时候你把异常抛出来,让调用SQL的UI捕获到这个异常,显示出来。所以说,无论是SQL里的还是UI里的异常捕获语句都是不能少的。因为SQL里只是负责把异常throw出来,而什么也没有做。这位达人的意思就是无论是在SQL还是在UI都有可能引发异常。如果你在SQL里把throw去掉,如果发生异常,那么程序就会中断,而UI里也捕获不到异常。而你在SQL里throw的异常最终也是在UI里被捕捉到并得到处理的。这是个人的见解,有可能不准确,仅作参考理解。
      

  10.   

    sql的中的异常最好不抛出,
    可以返回一个整形数据,然后对数据判断!!
      

  11.   

    我感觉在分层编程中,底层的catch最好能throw出去,并且附加上相关的信息,如
    cacth(Exception ex)
    {
      throw new Exception("xxx方法错误\n"+ex.message);
    }
    在其往上的各层中最好都加入以上信息(包括各自的异常数据),在未调通前一直保留异常的抛出,只有在调试接近完毕时,再屏蔽异常(如果你不想让客户看到很多阴暗面),但即使交付了,最好也能把必要的异常显示出来。这样对调试和解决问题都有非常好的帮助。另外,有些异常是由于数据库锁定造成的,这样需要判断是否需要重新运行程序,所以异常处理并没有想象的简单,也不应该太随意。
      

  12.   


    不对,异常是会层层传递的,我去掉sql层的try,catch,throw,sql层发生异常,也会被ui层try,catch到,那还要sql层的try,catch做什么?
      

  13.   

    Sql层
    try
    {
         dt = SQLHelper.ExecuteDataTable(SQLHelper.SQLHelper_SqlConn, str_SQL);
    }
    catch
    {
      throw new ExceptionWeb("查询失败。");
    }UI层
    先 catch ExceptionWeb
    再 catch Exception
      

  14.   

    UI弹出的出错信息是Exception里Message的内容
    而你重写了Exception的Message属性
    public override string Message 

    get { return DefaultVersion.GetMessage(_errNumber); } 

    DefaultVersion.GetMessage(0xFFFF)不就是"页面过期,请重新登录系统!"吗?没什么特殊的。