我考虑了一下,无法提出一个例子。为什么有人要捕获异常却什么也不做呢?能给我举个例子吗?也许这只是不应该做的事情。
我考虑了一下,无法提出一个例子。为什么有人要捕获异常却什么也不做呢?能给我举个例子吗?也许这只是不应该做的事情。
Answers:
我一直用D中的转换错误之类的方法来做:
import std.conv, std.stdio, std.exception;
void main(string[] args) {
enforce(args.length > 1, "Usage: foo.exe filename");
double[] nums;
// Process a text file with one number per line into an array of doubles,
// ignoring any malformed lines.
foreach(line; File(args[1]).byLine()) {
try {
nums ~= to!double(line);
} catch(ConvError) {
// Ignore malformed lines.
}
}
// Do stuff with nums.
}
就是说,我认为所有catch块中都应包含某些内容,即使这些内容只是解释为什么忽略该异常的注释。
编辑:我还想强调一点,如果您要执行类似的操作,则应注意仅捕获要忽略的特定异常。做一个普通的老人catch {}
几乎总是一件坏事。
我认为可以在不做任何事情的情况下吞下异常,甚至不记录异常的一个例子是在记录代码本身内部。
如果您尝试记录某些内容并遇到异常,则您无能为力:
这给您留下了“轻描淡写”的选项,可以悄悄地吞下它,使应用程序能够继续执行其主要任务,但是却损害了对其进行故障排除的能力。
空catch
块是大多数语言中的代码味道。主要思想是在异常情况下使用异常,而不是将其用于逻辑控制。所有异常都必须在某个地方处理。
采用这种方法的结果是,在对一个特定的应用程序层进行编程时,您有多种选择:
这实际上并没有留下任何可以做的空catch
块的空间。
编辑添加:假设您正在使用一种语言来编程,其中抛出异常是控制程序逻辑的常规方法(是的替代方法之一goto
)。然后,catch
用这种语言编写的程序中的空else
块非常类似于传统语言中的空块(或根本没有else
块)。但是,我相信这不是C#,Java或C ++开发社区推荐的编程风格。
在某些情况下,Java要求您处理绝对不会发生的异常。考虑以下代码:
try {
bytes[] hw = "Hello World".getBytes("UTF-8");
}
catch(UnsupportedCodingException e) {
}
Java平台的每个实现都需要支持以下标准字符集。
...
UTF-8
在不破坏Java平台的情况下,根本没有办法导致此异常。那么,为什么还要打扰呢?但是您不能简单地忽略try-catch-clause。
throw new Error(e)
,以确保绝对不会遗漏任何东西(或报告实际损坏的平台)。
作为一般规则,不可以。您要么将异常抛出堆栈,要么记录发生的事情。
但是,在解析字符串并将其转换为数字时,我经常这样做(尤其是在映射具有一次性使用功能并丢弃各种功能的项目中)。
boolean isNonZeroNumber = false;
try {
if(StringUtils.isNotBlank(s) && new BigDecimal(s).compareTo(BigDecimal.ZERO) != 0) {
b = true;
}
} catch(NumberFormatException e) {
//swallow this exception; b stays false.
}
return b;
在某些情况下,该异常并非完全例外。实际上,这是预料之中的。考虑以下示例:
/* Check if the process is still alive; exitValue() throws an exception if it is */
try {
p.exitValue();
processPool.remove(p);
}
catch (IllegalThreadStateException e) { /* expected behaviour */ }
由于java.lang.Process()中没有isAlive()方法,因此检查它是否仍然存在的唯一方法是调用exitValue(),如果进程仍在运行,则会抛出IllegalThreadStateException。
IMO在一个地方可以使用空catch语句。在预期例外的测试案例中:
try
{
DoSomething(); //This should throw exception if everything works well
Assert.Fail('Expected exception was not thrown');
}
catch(<whatever exception>)
{
//Expected to get here
}
我不相信发生异常时不会发出某种程度的警报-编程的目的之一不是改善代码吗?如果异常发生的时间是10%,并且您永远都不知道,那么异常总是那么糟糕,甚至更糟。
但是,我确实看到了另一面,如果异常在代码处理中没有真正的危害,那么为什么还要让用户接触它。我通常实现的解决方案是由我的logger类(即我在工作中写过的每个类)记录下来。
如果这是一个良性异常,那么我将调用Logger的.Debug()方法;否则,Logger.Error()(并且(可能)抛出)。
try
{
doWork();
}
catch(BenignException x)
{
_log.Debug("Error doing work: " + x.Message);
}
顺便说一下,在我的记录器实现中,仅当我的App.Config文件指定程序执行日志级别处于“调试”模式时,对.Debug()方法的调用才会记录该日志。
存在检查是一个很好的用例:
// If an exception happens, it doesn't matter. Log the initial value or the new value
function logId(person) {
let id = 'No ID';
try {
id = person.data.id;
} catch {}
console.log(id);
}
另一种情况是使用finally
子句时:
function getter(obj){}
function objChecker()
{
try
{
/* Check argument length and constructor type */
if (getter.length === 1 && getter.constructor === Function)
{
console.log("Correct implementation");
return true;
}
else
{
console.log("Wrong implementation");
return false;
}
}
catch(e)
{
}
finally
{
console.log(JSON.stringify(getter))
}
}
// Test the override of the getter method
getter = getter;
objChecker();
getter = [];
objChecker();
getter = {};
objChecker();
getter = RegExp;
objChecker();
getter = Function;
objChecker();
有一种建议允许在ECMAScript中省略与该案例和类似用例有关的catch绑定。
参考文献
我真正需要做的事情只有一次是使用控制台应用程序的日志记录类。有一个顶级全局捕获处理程序,该处理程序将错误发送到STDOUT,将错误记录到文件中,然后使用> 0错误代码关闭应用程序。
这里的问题是有时记录到文件失败。目录权限使您无法写文件,该文件被独占锁定,无论如何。如果发生这种情况,我将无法以与其他地方相同的方式处理异常(捕获,记录相关详细信息,包装更好的异常类型等),因为记录异常详细信息会导致记录器执行相同的操作(尝试写入文件)已失败。当他们再次失败时...您会看到我要去的地方。它陷入无限循环。
如果删除了一些try {}块,最终可能会在消息框中显示异常(而不是无声配置应用所需的消息)。因此,在写入日志文件的方法中,我有一个空的catch处理程序。这不会掩埋错误,因为您仍然会得到> 0错误代码,它只会停止无限循环并允许应用正常退出。
当然有一条评论,解释为什么它是空的。
(我本来打算早些发布,但是我只是害怕被遗忘。因为我不是唯一的一个人...)
优雅地关闭系统资源以从错误中恢复
例如。如果您在后台运行的服务无法向用户提供反馈,则可能不希望向用户推送错误指示,但是您确实需要以优雅的方式关闭正在使用的资源。
try
{
// execution code here
}
catch(Exception e)
{
// do nothing here
}
finally
{
// close db connection
// close file io resource
// close memory stream
// etc...
}
理想情况下,您可以在调试模式下使用catch来捕获错误并将其打印到控制台或日志文件中以进行测试。在生产环境中,通常期望后台服务在引发错误时不会中断用户,因此应抑制错误输出。