假设我们在业务层中有以下方法。告诉UI层出错的最佳做法是什么,并给出错误消息?该方法是否正常时返回一个空字符串,否则返回错误消息,或者它应该在包含捕获的异常的catch代码中抛出另一个异常?如果我们选择第二个变体,那么UI应该有另一个尝试,抓住哪个太多尝试,抓住可能。这是第一个变体的伪代码。
public String updateSomething()
{
try
{
//Begin transaction here
dataLayer.do1();
dataLayer.do2();
dataLayer.doN();
//Commit transaction code here
}
catch(Exception exc)
{
//Rollback transaction code here
return exc.message;
}
return "";
}
这是一个好习惯还是我应该在catch中抛出另一个异常(那么方法将无效)?
答案 0 :(得分:5)
我喜欢从我的业务层返回标准合约到我的UI图层。
看起来像这样:
public class ServiceOperationResult<T>
{
public bool Successful
{
get;
set;
}
public ServiceErrorType ErrorType
{
get;
set;
}
public string ErrorMessage
{
get;
set;
}
public T ReturnData
{
get;
set;
}
}
我使用泛型,以便每个服务都可以定义它发回的内容,标准错误标志告诉客户端应用程序发生了什么类型的错误(这些是元类型,如“内部错误”,“外部方错误” ,“业务规则验证错误”)然后应用程序可以以标准方式对这些错误类型做出反应。
例如,业务错误显示在红色错误标签中,而内部错误会重定向到错误页面(在Web应用程序中)或关闭表单(在Windows应用程序中)
我的宠物讨厌在网站上看到一个红色标签(我希望看到验证错误)并看到类似“数据库服务器拒绝您的连接”这样的风险,您只能使用字符串返回来运行错误数据。
答案 1 :(得分:2)
最好的方法是在一些更通用的类型中包装异常并重新抛出它。因此updateSomething()必须声明它可以抛出某种异常(例如:UpdateFailedException),并且在catch块中你应该包装异常。
public String updateSomething() {
try {
[...]
} catch ( SQLException e ) {
// rollback;
throw new UpdateFailedException(e);
}
}
但是捕获抽象异常类型并不是一个好主意。你应该只包装那些你知道的语义的东西。例如:SQLException,DataAccessException(Spring DAO)等。
如果你包装Exception,你很容易包装NullPointerException的InterruptedException。这可能会破坏你的申请。
答案 2 :(得分:1)
返回像这样的字符串有点不寻常(但是没有真正的原因)。更常用的方法是:
返回一个布尔值,并有一些设置错误消息的方法,通过记录它,设置一些全局“最后错误”值,或者有一个指向传递给你的方法的错误构造的指针更新;
有一个void方法,在失败时抛出异常,并在调用代码中处理它(如你所知)
我已经看到上述两种用法都被广泛使用了。很难说哪个是“最好的”。尝试与您正在使用的语言的习语和惯例和/或您正在使用的现有代码集/库(如果有)保持一致。
答案 3 :(得分:0)
可能最好的方法是拥有一个特定于图层的自定义异常类,一旦你在特定图层中捕获异常就会将自定义异常抛给调用图层,这将带来以下优势。
例如,您在业务层中捕获异常并想要通知表示层
public string DummyFunction
{
try
{
}
catch(Exception ex)
{
throw new businessException();
}
}