Exception handling 为什么空的捕获块是个坏主意?
我刚刚看到了一个例子,有人(包括乔恩·斯基特)说空捕集区真的是个坏主意?为什么会这样?在任何情况下,空捕捉都不是错误的设计决策吗Exception handling 为什么空的捕获块是个坏主意?,exception-handling,try-catch,Exception Handling,Try Catch,我刚刚看到了一个例子,有人(包括乔恩·斯基特)说空捕集区真的是个坏主意?为什么会这样?在任何情况下,空捕捉都不是错误的设计决策吗 我的意思是,举例来说,有时候你想从某处获得一些额外的信息(Web服务、数据库),而你真的不在乎你是否能获得这些信息。因此,您尝试获取它,如果发生任何事情,那没关系,我将只添加一个“catch(Exception ignored){}”,这就是所有的空的catch块通常被放入,因为编码器并不真正知道它们在做什么。在我的组织中,一个空的catch块必须包含一条注释,说明为
我的意思是,举例来说,有时候你想从某处获得一些额外的信息(Web服务、数据库),而你真的不在乎你是否能获得这些信息。因此,您尝试获取它,如果发生任何事情,那没关系,我将只添加一个“catch(Exception ignored){}”,这就是所有的空的catch块通常被放入,因为编码器并不真正知道它们在做什么。在我的组织中,一个空的catch块必须包含一条注释,说明为什么在异常情况下什么都不做是个好主意
与此相关的是,大多数人不知道try{}块后面可以跟catch{}或finally{},只需要一个。通常空的try-catch是一个坏主意,因为您正在默默地接受错误条件,然后继续执行。偶尔这可能是正确的做法,但通常这是一个迹象,表明开发人员看到了异常,不知道如何处理它,因此使用了一个空捕获来消除问题 这相当于在发动机警示灯上贴上黑色胶带 我认为,处理异常的方式取决于您所使用的软件的哪一层:。一般来说,这是一个坏主意,因为这是一种真正罕见的情况,在这种情况下,故障(更一般地说,是异常情况)被正确地满足,而没有任何响应。最重要的是,空的
catch
块是使用异常引擎进行错误检查的人常用的工具,他们应该先发制人地进行错误检查
说它总是坏的是不真实的…这是真的很少。在某些情况下,您可能不关心是否存在错误,或者错误的存在以某种方式表明您无论如何都无法对其进行任何处理(例如,在将以前的错误写入文本日志文件时,您会得到一个
IOException
,这意味着您无论如何都无法写出新的错误)一个空的catch块实际上是在说“我不想知道抛出了什么错误,我只想忽略它们。”
它类似于VB6在错误恢复下一步时的,只是抛出异常后try块中的任何内容都将被跳过
当某个东西发生故障时,这是没有帮助的。只有当确实存在异常时才应该抛出异常-发生了超出正常范围的事情。一个空的catch块基本上表示“有不好的事情发生了,但我不在乎”。这是个坏主意
如果您不想处理异常,请让它向上传播,直到它到达可以处理它的代码。如果没有任何东西可以处理异常,那么应该关闭应用程序。我认为,如果您捕获了一种特定的异常类型,您知道它只会因为一个特定的原因而引发,并且您期望出现该异常,并且真的不需要对其采取任何措施,那么就可以了
但即使在这种情况下,调试消息也可能是正确的。因为如果抛出异常,您将永远看不到它-无声失败是最糟糕的选择-您将得到错误的行为,并且不知道它发生在哪里。至少在那里放一条日志信息!即使这是“永远不会发生”的事情 空的catch块表示程序员不知道如何处理异常。它们正在抑制异常可能冒泡并被另一个try块正确处理。总是试着用你发现的异常做一些事情。这可能永远都不是正确的事情,因为你在默默地传递每一个可能的异常。如果有您期望的特定异常,那么您应该对其进行测试,如果不是您的异常,请重试
try
{
// Do some processing.
}
catch (FileNotFound fnf)
{
HandleFileNotFound(fnf);
}
catch (Exception e)
{
if (!IsGenericButExpected(e))
throw;
}
public bool IsGenericButExpected(Exception exception)
{
var expected = false;
if (exception.Message == "some expected message")
{
// Handle gracefully ... ie. log or something.
expected = true;
}
return expected;
}
我不会把事情延伸到说谁使用空的catch块是一个糟糕的程序员,他不知道自己在做什么
如有必要,我使用空的挡块。有时,我使用的库的程序员不知道他在做什么,甚至在没有人需要的情况下抛出异常
例如,考虑一些HTTP服务器库,我不关心服务器是否抛出异常,因为客户机已断开,并且<代码> index。HTML<代码>无法发送。
< P>我发现,当其他程序员完成时,空catch语句最烦人。我的意思是,当您需要调试来自其他人的代码时,任何空的catch语句都会使这样的任务变得更加困难。IMHO catch语句应始终显示某种类型的错误消息-即使未处理错误,也应至少检测到它(仅在调试模式下alt.on)很少有实例可以证明它是正确的。在Python中,您经常看到这种构造:
try:
result = foo()
except ValueError:
result = None
因此,可以(取决于您的应用程序)执行以下操作:
在最近的一个.NET项目中,我必须编写代码枚举插件DLL,以查找实现特定接口的类。相关代码位(在VB.NET中,对不起)为:
尽管即使在这种情况下,我也承认在某个地方记录失败可能是一种改进。我认为完全空的catch块是一个坏主意,因为无法推断忽略异常是代码的预期行为。在某些情况下,吞并异常并返回false、null或其他值并不一定是坏事。net framework有许多“try”方法都是这样的。根据经验,如果您接受异常,请在应用程序支持日志记录的情况下添加注释和日志语句。这与“不要使用异常来控制程序流”和“仅在异常情况下使用异常”密切相关。如果完成了这些操作,则只有在
result = bar()
if result == None:
try:
result = foo()
except ValueError:
pass # Python pass is equivalent to { } in curly-brace languages
# Now result == None if bar() returned None *and* foo() failed
For Each dllFile As String In dllFiles
Try
' Try to load the DLL as a .NET Assembly
Dim dll As Assembly = Assembly.LoadFile(dllFile)
' Loop through the classes in the DLL
For Each cls As Type In dll.GetExportedTypes()
' Does this class implement the interface?
If interfaceType.IsAssignableFrom(cls) Then
' ... more code here ...
End If
Next
Catch ex As Exception
' Unable to load the Assembly or enumerate types -- just ignore
End Try
Next
public static bool TryAction(Action pAction)
{
try { pAction(); return true; }
catch (Exception exception)
{
LogException(exception);
return false;
}
}
public static bool TryActionQuietly(Action pAction)
{
try { pAction(); return true; }
catch(Exception exception)
{
LogExceptionQuietly(exception);
return false;
}
}
public static void LogException(Exception pException)
{
try
{
AlertBox(pException, true);
LogExceptionQuietly(pException);
}
catch { }
}
public static void LogExceptionQuietly(Exception pException)
{
try { Debug.WriteLine("Exception: {0}", pException.Message); } catch { }
}
private void mCloseToolStripMenuItem_Click(object pSender, EventArgs pEventArgs)
{
EditorDefines.TryAction(Dispose);
}
private void MainForm_Paint(object pSender, PaintEventArgs pEventArgs)
{
EditorDefines.TryActionQuietly(() => Render(pEventArgs));
}
try
{
string a = "125";
int b = int.Parse(a);
}
catch (Exception ex)
{
Log.LogError(ex);
}