【发布时间】:2014-10-09 05:59:37
【问题描述】:
我的 Android 代码的行为很有趣。输入流应该并且确实会引发 IOException,这会正确地导致控制权转到// read an error stream。错误流被正确读取,调试器使用包含从错误流读取的预期字符的error_message 变量进入return error_message。然后它会正确地跳转到finally 块中的// no op,我添加它只是为了好玩。
然后,它会跳转到return "all hope lost";!!然后,它不会返回给调用者,而是进入一些 Android 系统代码,该代码会抛出 SecurityException 并带有关于缺少内容权限的消息。
删除finally 块没有任何影响——错误仍然存在。正在读取的流来自 HTTP URL 连接。如果服务器返回200 没有问题,但如果服务器返回400,它会通过上述奇怪的路径并尝试抛出奇怪的SecurityException。
try {
// read an input stream into message
return message;
} catch (IOException outer) {
try {
// read an error stream into error_message
return error_message;
} catch (IOException inner) {
return "all hope lost";
}
} finally {
// no op, just to step debugger
}
更新:发布确切的代码和调试跟踪。
try {
/*x*/ BufferedReader buffered_reader =
new BufferedReader(
new InputStreamReader(
new BufferedInputStream(http_url_connection.getInputStream())));
StringBuilder string_builder = new StringBuilder();
String line;
for (line = buffered_reader.readLine();
line != null;
line = buffered_reader.readLine()) {
string_builder.append(line);
}
return string_builder.toString();
} catch (IOException io_exception) {
this.io_exception = io_exception;
BufferedReader buffered_reader =
new BufferedReader(
new InputStreamReader(
new BufferedInputStream(http_url_connection.getErrorStream())));
StringBuilder string_builder = new StringBuilder();
try {
for (String line = buffered_reader.readLine();
line != null;
line = buffered_reader.readLine()) {
string_builder.append(line);
}
/*y*/ String error_message = "server error: " + string_builder.toString();
return error_message;
} catch (IOException exception) {
String level_2_error_message = "level 2 error: " + exception.getMessage();
return level_2_error_message;
} finally {
return "foo";
}
}
/*x*/ 行会按预期跳转到第一个 catch。然后按预期执行直到/*y*/ 的所有行。那么奇怪的事情是/*y*/ 行没有完成,如果没有finally 或finally,控制立即转到下一个catch 块。如果有 finally 则不会获得最后一个 catch 块。
/*y*/ 行上的字符串缓冲区的内容看起来非常好——来自服务器的 20 个字符的字符串。
【问题讨论】:
-
你确实意识到,你可以做一些像
Log.e(this.getClass().getSimpleName(), "Error in method insertMethodNameHere()", exception);这样的事情,而不是这种疯狂的尝试,这样你就知道出了什么问题,对吧? -
@Zhuinden 不是为了调试。异常来自网络连接,并且可能在用户在现场使用应用程序时发生。所以我看不出
Log.e(...)会有什么帮助。 -
如果在最后一个块中放置一个 return 语句,行为仍然是一样的吗?
-
@eldjon 是的,还是一样。但我对这个问题有更新。发布确切的代码和跟踪。
-
如果不知道实际的错误,就很难找到原因。
标签: java android exception try-catch ioexception