void connectOverNetwork() throws Exception {
try {
final JSONObject response = make network call;
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new Exception("message replied with error");
}
} catch (final Exception e) {
LOG.error("---- bar message ---");
throw new SvcException("failed to connect over network");
}
}
在上面的代码中,我抛出了带有失败消息的异常。 同时,由于无法通过网络连接,我也会引发错误。
但是,如果我为!success
抛出异常,它将再次被捕获,从而导致重复记录。如果我只想登录bar message
,我不想打印foo message
。
如何防止它发生?
答案 0 :(得分:3)
在response
语句之后验证try-catch
。
JSONObject response = null;
try {
response = /* make network call */;
} catch (final Exception e) {
LOG.error("---- bar message ---");
throw new SvcException("failed to connect over network");
}
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new Exception("message replied with error");
}
我不建议捕获Exception
-太笼统了,我建议您将其范围缩小到更具体的异常类型。
答案 1 :(得分:1)
如果将其移到try
块之外怎么办。无论如何,第一个try..catch
的原因是从网络调用中捕获了任何异常。
JSONObject response = null;
try {
response = make network call;
} catch (final Exception e) {
LOG.error("---- bar message ---");
throw new SvcException("failed to connect over network");
}
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new Exception("message replied with error");
}
答案 2 :(得分:0)
创建自己的异常类型,不要捕获它。
try {
do stuff
if (condition)
throw new MyCustomException("error")
} catch (IOException e) {
log and rethrow
}
答案 3 :(得分:0)
首先,让我指出您的代码中的错误。您的方法声明它抛出Exception,但没有。它引发SvcException。这就是“ throws”子句应该说的。 (无论如何,您永远都不要说“引发异常”。您应该明确说明它引发的异常类型。)其余的答案取决于您模糊的描述“进行网络呼叫”是否引发异常。
否则,您的方法应如下所示:
void connectOverNetwork() throws SvcException {
final JSONObject response = makeNetworkCall();
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new SvcException("message replied with error");
}
}
但这是不现实的。您的“进行网络调用”代码可能会抛出类似IOException的错误。在这种情况下,您的代码应如下所示:
void connectOverNetwork() throws SvcException {
try {
final JSONObject response = makeNetworkCall(); // throws IOException
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new SvcException("message replied with error");
}
} catch (final IOException e) {
LOG.error("--- foo message ---");
throw new SvcException("failed to connect", e); // wrap e inside SvcException
}
}
请注意,我将捕获的IOException包装在SvcException中。如果您的SvcException不这样做,则可以重写它以便可以,或者在抛出它之前调用其initCause()
方法。重新抛出其他异常时,应始终包含原始异常。
还请注意,我不会麻烦抛出,而是捕获并重新抛出IOException。当我检测到故障时。我只是抛出需要抛出的异常。这意味着我需要在两个不同的地方记录foo消息。在大多数情况下,应该避免重复执行一行代码,但是对于日志记录来说,这很好。
但是这段代码有点混乱。我将成功测试与可能的IOException分离开来进行清理。所以我会这样写:
void connectOverNetwork() throws SvcException {
JSONObject response; // no need to initialize this.
try {
response = makeNetworkCall(); // throws IOException
} catch (final IOException e) {
LOG.error("--- foo message ---");
throw new SvcException("failed to connect", e); // wrap e inside SvcException
}
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new SvcException("message replied with error");
}
}
请注意,在try循环之前声明了响应。它没有被初始化,因为没有值它不可能达到!response.getBoolean(SUCCESS)
测试。如果makeNetworkCall()引发异常,它甚至不会到达该行。