My Android code is behaving funny. The input stream should and does throw an IOException, which correctly causes control to go to // read an error stream
. The error stream is read correctly and the debugger steps to return error_message
with the error_message
variable containing expected characters read from error stream. It then correctly steps to the // no op
in the finally
block, which I added just for kicks.
And then, it steps to return "all hope lost";
!! Which then, instead of returning to the caller, steps into some Android system code that throws a SecurityException
with a message about lack of content permissions.
Removing the finally
block has no impact -- the bug still happens. The streams being read are from an HTTP URL Connection. No problems if server returns 200
but if server returns 400
it goes through the weird path described above and tries to throw the weird 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
}
Update: Posting exact code and debug trace.
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";
}
}
Line /*x*/
causes the jump to the first catch
as expected. All lines up to /*y*/
are then executed as expected. Then the weird thing is that line /*y*/
does not complete and control immediately goes to either the next catch
block if there is no finally
or to the finally
. If there is a finally
then it does not to got the last catch
block.
The contents of the string buffer on /*y*/
line look perfectly fine -- a 20 character string from the server.