有一天,我出现在采访中,面试官问我global.asax的目的是什么。我说这是为了捕获像Session_Start等特定事件。然后他说你如何在代码中进行异常处理?我说我们将语句包装在try catch块中。然后他说你会为代码中的所有按钮点击事件做这个吗?这是如此乏味和重复。 OOP在这里如何形成?他说你应该总是在global.asax中的Application_Error中捕获错误。我说OOP并没有说你应该抓住这个事件中的所有错误。我们应该始终捕获特定的异常,并且应该在那些相应的处理程序中。我们在采访中陷入了相当大的争吵,我直截了当地说,我不同意你的看法。
你能告诉我你们如何处理服务器端的异常?
提前致谢:)
答案 0 :(得分:15)
我找到的简短答案是,如果您想要保留工作,即使您不同意,也要按照指示编码的方式进行编码。
但是,如果您只捕获Global.asax中的错误,那么您将失去本地变量调试和优雅的错误处理。 Global.asax中处理的错误通常不会优雅地失败。
我通常会在Global.asax中发现任何未处理的错误,但对我来说,只处理这个问题就像没有刹车,因为它有安全气囊。 (是的,我爱隐喻)
答案 1 :(得分:8)
所有这一切的关键是预期和意外例外之间的区别。在编写代码时,应明确捕获可能发生的异常。
完美的例子是分裂。您将分子除以分母。你知道除以零会引发异常。此时,您可以捕获期望的异常来处理或在遇到异常之前显式抛出(基本上由您的要求决定)。如果您什么也不做,意外例外就会发挥作用。
根据大多数软件编写方式的性质,未处理的异常对于用户体验来说很差,不幸的是,更常见的异常类型。它们是由频繁的代码流失,缺乏对要求的理解,对更广泛的系统的有限知识以及仅仅是纯粹的懒惰所引入的。通常,遇到这些问题时,会导致软件操作方面的突然变化。
全局异常处理程序的目的是/优雅地恢复或通知用户在收集尽可能多的有价值信息时出现问题./就个人而言,我发现这些异常应以有意义的方式记录并解决尽快地。如果遇到这些问题,则可能是未执行或处理预期条件,或者代码中存在导致应用程序进入无效状态的逻辑问题。
正确使用,全局异常处理程序是一个很好的安全网,可以用来帮助提高整个代码的质量。所涉及的风险通常来自于仅依赖于全局异常处理程序,或者忽略对报告的内容采取行动。
答案 2 :(得分:8)
你只能在做某事时才会发现错误(而不只是记录它们),这是非常罕见的。
例如,抓住SqlExceptions
重试死锁是合理的:
catch(SqlException exception) {
if (exception.Number == 1205)
// call retry code
else
throw;
}
如果您要记录这些异常并显示通用的“aw snap”消息,那么捕获页面处理程序方法中的每个异常都是不合理。将该代码放在一个位置:Application_Error
。
要处理您可以预见的问题(例如除零错误),您应该首先防止无效输入或处理之前生成异常的条件:
// Make sure the exception never happens and provide meaningful feedback
if (divisor == 0) {
txtErrorMessage.Text = "Enter a value greater than zero.";
return;
}
txtQuotient.Text = dividend / divisor;
答案 3 :(得分:1)
一个选项是让站点中的所有页面都扩展一个Page类,该类处理System.Web.UI.TemplateControl的Error事件。
如果您无法让站点上的所有页面扩展到公共基类,则Application_Error非常有用。