三层开发错误在哪层捕捉?
用三层开发,DBAccess(数据访问层),Bil(逻辑层),WebUI(界面层)
在界面层里调用 BIl.InsertOrder
Bil层里又调用 DBAccess.execute(',',')更新到数据库
那么如果出现错误一定是在 DBAccess.execute(',',')出现错误
这时要在哪一层捕捉进行错误处理,并显示给用户看。
请大家说说都是怎么处理的!
问题点数:50、回复次数:52Top
1 楼iuhxq(小灰)回复于 2005-09-15 08:57:06 得分 2
关注,可能在数据访问层处理比较方便,但不方便给用户看Top
2 楼8LY8Apollo(阿波罗)回复于 2005-09-15 09:03:48 得分 2
我在最底层来捕获异常的,各位呢?Top
3 楼happer6012()回复于 2005-09-15 09:04:02 得分 2
还是数据层比较方便Top
4 楼lovebanyi(风云)回复于 2005-09-15 09:08:22 得分 2
可能出错的地方就用异常处理了. 而不应该分哪一层吧.Top
5 楼smin1994(smin1994)回复于 2005-09-15 09:09:05 得分 2
逐层catch,可以返回到页面上Top
6 楼pwqzc(吴旗娃徒也~~老鼠粮仓之路)回复于 2005-09-15 09:13:01 得分 2
最底层catch
然后返回个值
其他的层只要这个值就可以拉
层层catch乱费资源Top
7 楼swordragon(古道热肠)回复于 2005-09-15 09:14:25 得分 2
数据访问层捕获的异常 -〉逻辑层 -〉界面层
1、数据访问层捕获的异常:
可以写log文件,然后抛出一个自定义的异常到逻辑层。
2、逻辑层:
可以写log文件,做错误解析,给界面层一个返回值。
3、界面层:
应该根据逻辑层的返回值等作错误处理,比如提示框等告知用户。
Top
8 楼xjtandqt(重在参与)回复于 2005-09-15 09:15:09 得分 0
我认为不能在数据访问层捕获并处理,sqlhelper里好象都没有捕获错误。
继续关注!
smin1994(smin1994)的逐层catch,可以返回到页面上要怎么做。Top
9 楼cherish58()回复于 2005-09-15 09:17:49 得分 2
做一个公共的捕获异常页面,把异常都throw这个页面里边去。再显示给用户看Top
10 楼xjtandqt(重在参与)回复于 2005-09-15 09:18:01 得分 0
swordragon(古道热肠) 的方法不错。
有没有例子参考一下。Top
11 楼rhs(释放自己)回复于 2005-09-15 09:21:35 得分 0
我觉得所有层都要,因为每一层都有可能发生异常,都写入写log文件就行了,给用户看都没有什么用,用户看得明白吗?Top
12 楼xjtandqt(重在参与)回复于 2005-09-15 09:33:19 得分 0
在这里其它层的错误暂时不考虑,
数据层出现的错误是最头疼的。因为这时后出现的错误用户是看不懂的,所以要处理一下显示出来让用户看的懂。比如说插入一条数据库已经存在的数据,这时侯就会出现主建冲突等。显示给用户看的时候变成:"改记录已经存在,请修改!"
采用分层后就不好处理了!Top
13 楼jyk(今天由我来写的代码,明天就让程序自己完成!喜欢编程。和气生财。共同提高。共同进步!)回复于 2005-09-15 09:45:01 得分 2
同意 pwqzc(吴旗娃徒也~~老鼠粮仓之路)
异常不做当然要在最底层了 ,比如 DBAccess(数据访问层) 。
然后可以有几种处理方式:
1.记录到日志
2.用 System.Web.HttpContext.Current.Response.Write("错误信息");直接输出。
3.设置一个属性,比如ErroeMsg ,执行一个方法后,判断这个属性就行了,而不用catch。因为catch太慢,而且浪费资源。
以上这几种各有优缺点。最不应该用的就是层层catch吧。很浪费的,代码也会长不少。
Top
14 楼sukaru(逍遥子)回复于 2005-09-15 09:51:07 得分 2
尽量考虑更多可能的异常,详细的异常的代码写入log文件,然后在ui给用户一个尽量简单易懂的出错提示,并能够提供用户自己解决的方法,毕竟不能把用户当成专业人员,而且我们面对的用户大多数都属于急功近利的那种,如果仅仅给一个出错提示 那么用户对软件的印象可能会大打折扣。Top
15 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 10:19:04 得分 2
自己定义一个异常类,在DBAccess层捕获错误。Top
16 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 10:23:43 得分 2
public class DBException:Exception
{。。。。。}
public class DBAccess
{
public void OpenConnection()
{
try
{
DBConnection.Open();
}
catch(Exception e)
{
DBException dbe=DBException.GetDBException(ErrCode.ExecuteNonQuery,e);
throw(dbe);
}
}
}Top
17 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 10:27:37 得分 2
public class DBException:Exception
{
.
.
.
.
public static string GetDBErrMsg(ErrCode DBErrCode)
{
string ErrMsg="";
switch(DBErrCode)
{
case (ErrCode.OpenCn):
{
ErrMsg= "打开数据库连接错误!——";
break;
}
case (ErrCode.ExecuteReader):
{
ErrMsg= "读数据库错误!——";
break;
}
case (ErrCode.ExecuteNonQuery):
{
ErrMsg= "执行数据库命令错误!——";
break;
}
case (ErrCode.BeginTransaction):
{
ErrMsg= "开始数据库事务处理错误!——";
break;
}
}
return ErrMsg;
}
}Top
18 楼catchdream(星剑)回复于 2005-09-15 10:28:48 得分 2
我常用的是:在底层只写一下日志。然后在显示层捕捉所有异常(一般而言,不能显示调试中那个出错的黄页给用户看,否则用户不知所措了。)对典型异常,转换成用户可以理解的方式(比如数据库数据重复,通过查找异常中的关键字即可知道)。其他错误进行屏蔽。
建议在不是文档很正规的情况下,不要使用自定义异常,否则,人员一旦变动,或者即使是自己,过了一段时间,都不知道自定义的是什么了。而使用原始异常就没这个问题--一家之言Top
19 楼xjtandqt(重在参与)回复于 2005-09-15 10:32:25 得分 0
谢谢大家,
请继续关注!有好的方法都来说说。!Top
20 楼liuqinglq(白菜)回复于 2005-09-15 10:33:37 得分 2
我是进来学习的^_^Top
21 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 10:41:18 得分 2
............
建议在不是文档很正规的情况下,不要使用自定义异常,否则,人员一旦变动,或者即使是自己,过了一段时间,都不知道自定义的是什么了。而使用原始异常就没这个问题--一家之言
----------------------------------------------------------------------------------
RE:catchdream(星剑)
你知道异常类是写在什么地方的吗?人员变动和自定义异常有什么关系?你意思是,换了个人,不用自定义异常类,就不用熟悉以前的代码了?对于自己写的异常类,自己都看不懂,那只能说这个类是你盗窃的!还有一点!!自定义异常类,和文档规范不规范是没有关系的!异常类是写在类模板的数据访问层里面的(至少我是这样)。你知道什么叫分层吧??Top
22 楼stzzh(北大菜鸟)回复于 2005-09-15 10:44:39 得分 2
让它往外抛,在UI层捕获Top
23 楼catchdream(星剑)回复于 2005-09-15 10:59:17 得分 2
to liuxiang027(Nail.柳翔)
sigh ,你无非是捕捉系统抛出的异常,另外抛出自己的异常吧,我问你,你确定在这个系统中只有你定义了异常类?要是没个人都定义一个,那你自己去看代码吧,另外,你作的每个系统定义的异常类是相同的么?要是这样,那么恭喜你了,否则,挑战自己的记忆力吧,我是觉得我没有这么好的记忆力的。Top
24 楼stoneyu(小赖-Love,love,love.)回复于 2005-09-15 11:00:20 得分 2
关注中.......等待高手继续讨论.........Top
25 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 11:12:49 得分 2
RE: catchdream(星剑)
数据访问层的代码,你们公司是一个系统一个访问层吗?那你们还要访问层做什么啊?每个公司为什么要定义自己的一套类模板?一个类模板里面会有多个异常类吗??对!我们公司的异常类,就是我定义,因为类模板就是我来写,别人直接用。
case (ErrCode.OpenCn):
{
ErrMsg= "打开数据库连接错误!——";
break;
}
case (ErrCode.ExecuteReader):
{
ErrMsg= "读数据库错误!——";
break;
}
case (ErrCode.ExecuteNonQuery):
{
ErrMsg= "执行数据库命令错误!——";
break;
}
case (ErrCode.BeginTransaction):
{
ErrMsg= "开始数据库事务处理错误!——";
break;
}
你认为这几个CASE不是所用访问数据通用的?请问一下!在什么系统下不能用这几个CASE。当然,在用的过程中,发现有不足的!随时加CASE!对于扩展性,也是没有问题的!
请继续提出你的高见!Top
26 楼zyug(LovlyPuppy)回复于 2005-09-15 11:20:16 得分 2
异常是向上层堆栈递归的
总的来说在UI层是一定会捕获的
如果想知道在哪里抛出的 Exception 已经提供了那样的功能
同时在一个地方统一处理也便于管理Top
27 楼saintqiqi(钻石星辰(www.saintzone.net))回复于 2005-09-15 11:21:22 得分 2
关注~~
markTop
28 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 11:29:59 得分 2
zyug(LovlyPuppy)
我很赞成你的意见。
-----------------------------------------------------------------
异常是向上层堆栈递归的
总的来说在UI层是一定会捕获的
如果想知道在哪里抛出的 Exception 已经提供了那样的功能
同时在一个地方统一处理也便于管理
-----------------------------------------------------------------
我的思想也和你一样。所以我在访问层里面,对每个对象内部进行异常的捕获。
例(如上方法):OpenConnection()这个方法,做为对象来用,出现异常就可将该对象的异常抛出来显示!并不需要一层一层的捕获。
(欢迎不同意见提出,共同讨论)
Top
29 楼edwardfay(都说养儿为防老,山高水远他乡流)回复于 2005-09-15 11:30:36 得分 2
得把错误信息throw出来啊Top
30 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 11:35:38 得分 2
回复人: liuxiang027(Nail.柳翔) ( ) 信誉:100 2005-09-15 10:23:00 得分: 0
public class DBException:Exception
{。。。。。}
public class DBAccess
{
public void OpenConnection()
{
try
{
DBConnection.Open();
}
catch(Exception e)
{
DBException dbe=DBException.GetDBException(ErrCode.ExecuteNonQuery,e);
throw(dbe);
}
}
}
Top
31 楼catchdream(星剑)回复于 2005-09-15 12:05:07 得分 0
to liuxiang027(Nail.柳翔)
高见不敢,我开始就说处了一个前提,是文档齐全,我问你,没有文档,别人用的异常类时,是自己翻到你的代码来看你自己怎么定义的?而且要真定义异常类,系统中不可能只有数据库连接的异常类吧,那些可不是相同的吧。。。Top
32 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 12:25:08 得分 0
RE:catchdream(星剑)
我都说了,是捕获数据访问的异常,这里讨论的也是数据访问的异常。你的意思也就是说,没有自定义异常类的话,类模板就不需要文档?就不用告诉别人怎么用里面的对象?既然需要,既然有的话!!那教人用类模板中的异常类,就是必然的!既然是必然的,为何一定要停留在牛角尖上?教人用的方式,也不一定要用文档的形式,配合默契的开发小组(技术水平平均),可以把使用类模板文档的时间给节约下来。
所以,也不一定是非要文档齐全,才能自己自定义异常类的,首先请你搞清楚,异常类的好处在什么地方?如果按CMM标准做开发,光写齐全的文档都写死你,你也不用做开发了,可以当文员了。Top
33 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 12:30:38 得分 0
而且要真定义异常类,系统中不可能只有数据库连接的异常类吧,那些可不是相同的吧。。。
-------------------------------------------------------------------------------------
我那只是做列的一个例子。我已经说的很清楚了!访问层里面的方法,都会当做对象来用,然后每个对象都有异常的捕获,哪怕是数据的操作。都是一样。
Top
34 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 12:36:53 得分 0
case (ErrCode.OpenCn):
{
ErrMsg= "打开数据库连接错误!——";
break;
}
case (ErrCode.ExecuteReader):
{
ErrMsg= "读数据库错误!——";
break;
}
case (ErrCode.ExecuteNonQuery):
{
ErrMsg= "执行数据库命令错误!——";
break;
}
case (ErrCode.BeginTransaction):
{
ErrMsg= "开始数据库事务处理错误!——";
break;
}
从以上几个CASE中都能看出,捕获的异常有数据库的连接、读取数据、执行SQL命令及事物的处理。
你认为这些抛出的异常不全吗?那你可以提出来。
Top
35 楼littleRoc()回复于 2005-09-15 13:58:24 得分 0
web方式的处理不多,我做的比较多的是cs的程序,处理方式一般是每层都做错误捕捉,捕捉错误后在错误中加入当前出错位置信息,比如当前函数的名称、类名称等,然后加上错误的代码、描述后再把错误抛出去,这样做的好处是出了错误很容易定位错误是哪里报出来的,解决问题很方便,千万不要catch了错误就不处理了,这样做以后程序就没法维护了,客户端报一个错误,可能要把所有的代码翻过来才能找到哪里出了问题。Top
36 楼littleRoc()回复于 2005-09-15 14:01:02 得分 0
对了,忘了说了,如果在最外层,为了界面友好,可以对错误的description进行一下处理,也就是 liuxiang027(Nail.柳翔) 所说的那样,这样可能对用户更友好写。但是千万要把出错的位置信息也一并显示出来(或者放到自己可以找到的地方),方便程序调试、修改Top
37 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 14:07:11 得分 0
WEB 和 WIN其实也是一样的。分层处理数据的好处就是,哪层有错,就修改哪层。访问层传出的如果只是封装了数据访问的对象。只用对这个对象的内部做异常的捕获。UI层出的错,只用修改UI层,UI层基本上都不是操作数据的访问的了,操作的全部都是对象。逻辑层出错,只用修改逻辑处理层。每层负责各自的活动,层次分明的时候,程序报错一看就知道是哪一层有问题。Top
38 楼catchdream(星剑)回复于 2005-09-15 14:40:33 得分 0
其实我刚才本想说的是除数据操作以为的异常。。。
不过,既然你这么说,我举个简单例子:在数据库更新操作中,可能多种异常,如:关键字和现有冲突,操作表锁定,关联表被锁定。。。。
那么,在你的例子里,是不是都抛出一个执行数据库命令错误呢?Top
39 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 16:45:36 得分 0
对,很对!!抛出这个异常,我就知道是执行命令的时候有错,这个时候,我就检查这段命令就行了,别的就不用管。对于这,你有其他的见解吗?不会是连这都不知道吗?每层各自负责各自的活动。Top
40 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 16:47:58 得分 0
回复人: catchdream(星剑) ( ) 信誉:100 2005-09-15 10:59:00 得分: 0
我常用的是:在底层只写一下日志。然后在显示层捕捉所有异常(一般而言,不能显示调试中那个出错的黄页给用户看,否则用户不知所措了。)对典型异常,转换成用户可以理解的方式(比如数据库数据重复,通过查找异常中的关键字即可知道)。其他错误进行屏蔽。
建议在不是文档很正规的情况下,不要使用自定义异常,否则,人员一旦变动,或者即使是自己,过了一段时间,都不知道自定义的是什么了。而使用原始异常就没这个问题--一家之言
-------------------------------------------------------------------------------------
这些就是你本想说的是数据库操作以外的异常?
值得深思。。。。。。。Top
41 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 16:56:54 得分 0
SORRY!上面语气或许有点激动了。今天的压力有点大,所以不知觉中语气重了点,请谅解!Top
42 楼catchdream(星剑)回复于 2005-09-15 17:13:30 得分 0
sigh.
可是对于我说的这3种情况:关键字和现有冲突,操作表锁定,关联表被锁定。。。。要求不同的处理方式呢?比如:关键字和现有冲突,我要求清楚给用户提示信息,让他修改关键自,而其他两种情况则屏蔽掉(只写日志以便复查用),怎么用你的Exception来实现呢,是不是扩充?那我再有其他情况,再扩充?Top
43 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 17:28:40 得分 0
恩,对。只要能扩充的,就继续扩充这个异常类。
-----------------------------------------------------------------------------------
回复人: zyug(LovlyPuppy) ( ) 信誉:100 2005-09-15 11:20:00 得分: 0
异常是向上层堆栈递归的
总的来说在UI层是一定会捕获的
如果想知道在哪里抛出的 Exception 已经提供了那样的功能
同时在一个地方统一处理也便于管理
-----------------------------------------------------------------------------------
这位朋友已经说的很清楚了,我也很赞成他的意见,如果你有不同的意见,也可以提出!Top
44 楼cabxyz(cab)回复于 2005-09-15 17:32:48 得分 0
用日志 错误不让用户看到 否则影响客户的心情Top
45 楼liuxiang027(Nail.柳翔)回复于 2005-09-15 17:41:55 得分 0
为什么要报错?你们公司不做压力测试?测试的时候不修改??修改的时候,看着友好的异常提示去找错误?
我有个朋友,在武大软件研究所,他说他曾经做了一个项目,给用户用了4,5年。系统从来没有出现过对数据操作上的错误。我觉得这个是很重要的!如果以来友好的异常提示来应付客户,当用户输入大量数据后,使系统数据库崩溃或出现严重的错误!这是谁都无法承担的责任,特别是像我们给政府机关做项目的!尽量要把出错率降低为0。虽然这是很难实现的,但是至少我们是在努力的做,而不是用友好提示来应付客户。Top
46 楼webdiyer(.net资源精华—www.dotneturls.com)回复于 2005-09-15 17:54:07 得分 0
我的看法是:在其它层中出错都抛出异常,而在表现层处理处理这些异常Top
47 楼jyk(今天由我来写的代码,明天就让程序自己完成!喜欢编程。和气生财。共同提高。共同进步!)回复于 2005-09-15 19:07:36 得分 0
其实了情况是很复杂的了。
首先呢要先弄清楚概念:哪些是错误,哪些是异常......
哪些是可以预见的,哪些是不可预见的。
在编写的时候常出现的是哪些错误
在上线运行后可能会出现的是哪些错误
怎么处理机即方便程序员调试,又不会让客户头晕。
呵呵。好多好多呢!
Top
48 楼xjtandqt(重在参与)回复于 2005-09-16 08:15:29 得分 0
谢谢大家参与,看来我这个问题提的很有意义!
我准备用liuxiang027(Nail.柳翔) 的方法来捕捉数据访问层的错误,然后在表示层有选择的显示。
大家有好的方法多说说啊,三人行必有我师焉嘛Top
49 楼philipsslg(刮开中大奖(█))回复于 2005-09-16 08:49:49 得分 0
我来mark一下Top
50 楼blake_lejp(Blake Stone)回复于 2005-09-16 09:50:11 得分 0
每一次都要捕获的Top
51 楼shigangyuan(爬上墙头等红杏)回复于 2005-09-16 11:32:18 得分 0
关注Top
52 楼biduan(笔端)回复于 2005-09-16 12:13:22 得分 0
数据层确实是比较难捕获异常
关键是开发的时候最好写测试代码
并且都不异常的信息记录在日志里面Top




