学习记录错误。 这是我项目中代码的基本结构。
我被告知try块必须只放在事件处理程序中。
但是在记录错误时,需要知道哪种方法导致了错误。
所以,在这种情况下,我是否应该继续AllIsFine()
& SaveData()
。
如果是,那么它应该记录错误还是throw
。
什么是最佳/标准做法。
DataContext objDataContext = new DataContext();
protected void btn_Click(object sender, EventArgs e)
{
try
{
if(AllIsFine())
{
objDataContext.SaveData();
}
}
catch(Exception ex)
{
//some handling
}
}
private bool AllIsFine()
{
//some code
}
编辑:当然,我们会尝试看到它永远不会引发异常,但却不实用。我这样看着它。部署时,我唯一的访问权限就是日志,并且需要尽可能多地获取信息。所以在这种情况下,(并且使用这种结构),你建议在哪里保留try catch
答案 0 :(得分:6)
我被告知try块必须只放在Event中 处理
事实并非如此 有不同类型的例外,一些你需要处理,一些你应该抛出,一些你应该抓住,一些你不应该。请阅读this。
要点:
throw
而不是throw ex
(它会重置调用堆栈)IndexOutOfRangeException
,NullPointerException
,ArgumentNullException
),而不是执行操作并捕获异常
- 不要抓住致命的例外;无论如何你无能为力,并试图让它变得更糟。
- 修复你的代码,使其永远不会触发一个愚蠢的异常 - 一个"索引超出范围"生产代码中绝不应发生异常。
- 尽可能通过调用那些引入非异常的烦恼方法的“尝试”版本来避免烦恼的异常 情况。如果你不能避免调用一个令人烦恼的方法,赶上它 令人烦恼的例外。
- 始终处理表示意外外生条件的异常;一般来说,预期是不值得或不实际的 每一次可能的失败试试操作并做好准备 处理异常。
答案 1 :(得分:2)
try-catch语句包含一个try块,后跟一个或多个catch子句,这些子句为不同的异常指定处理程序。
object o2 = null;
try
{
int i2 = (int)o2; // Error
}
可以在同一个try-catch语句中使用多个特定的catch子句。可以在catch块中使用throw语句来重新抛出catch语句捕获的异常。您可以捕获一个异常并抛出不同的异常。执行此操作时,请将您捕获的异常指定为内部异常
catch (FileNotFoundException ex)
{
// FileNotFoundExceptions are handled here.
}
catch (InvalidCastException ex)
{
// Perform some action here, and then throw a new exception.
throw new YourCustomException("Put your error message here.", ex);
}
throw ex;
基本上就像从那一点抛出一个异常,因此堆栈跟踪只会发送到你发出throw ex;
语句的位置
答案 2 :(得分:2)
但是在记录错误时,需要知道哪种方法 导致错误。
你应该使用调用堆栈。
尽可能多地尝试防止异常,而不是捕获它们,如果你想捕获一个错误,尝试捕获一个特定的错误,我的意思是,不要尝试捕获异常,而是像InvalidCastException那样具体。
捕获错误后,您应该记录异常,但不要抛出异常来记录它。
答案 3 :(得分:1)
我想了一会儿你的问题,即使已经回答了,我想分享一下我的想法。
在谈论异常处理时,您必须记住是的异常: 当代码无法按预期运行时,会发生异常,从而导致应用程序的行为/状态不一致。 这个想法引导我们做出一个重要规则:不捕获您无法处理的异常! Exception系统提供安全性。考虑连接到数据库的会计软件,连接会引发异常。如果您只记录异常并且没有向用户提供任何关于此的通知,他将开始使用该软件,当他尝试保存时,数据将丢失!
你知道, 处理异常非常重要:
决定也受到架构的影响:
让我们回到数据库异常场景:您无法在UI层中处理特定的异常,例如MySQL特定的异常(MySqlException
),因为这会导致从View层到特定的Model层实现和分层架构的边界将被打破。但是,这不是主题,因为您的问题是关于记录异常,但是您应该牢记这一点,并且可能会这样考虑:捕获具体库的异常或属于特定层/依赖项的异常发生和记录他们和 throw new
,更通用(可能是自创)的例外。这些异常可以在视图层中处理并呈现给用户。
的问题也很重要。由于伐木被视为一个跨领域的问题。您可以考虑一个AOP框架,或者正如我在评论中建议的那样,使用装饰器模式。您可以通过控制使用的基本反转来组成日志记录装饰器,并且通过将所有内容包装在try-catch
块中,您的代码将更加清晰。
如果您在应用程序中使用(或计划使用)DI容器,您还可以使用拦截,这将允许您通过指定的行为动态包装方法调用(如try-catch
)。
处理您可以处理它们的异常,并记录它们,从中获取最相关的数据(例如上下文)来重现错误。但请记住,异常是一种安全机制 - 它会在应用程序不再处于安全状态时停止它 - 当您不转发异常时(使用throw
)并只记录它们,这可能导致不是最好的用户体验。
如果您想要任何代码示例,只需要求它们;)