Closed hflzh closed 6 years ago
Hi @gnodet , I tried with the fix in 28e36be, LineReader.readLine() was not able to proceed because of EndOfFileException, the lines following the 'M' were never read and printed out.
I finally figured it out, I have to call terminal.resume() in the catch block to create a new pump thread to read in the inputs.
Hi @gnodet ,
If I move 'M' to the first line, that is
String[] lines = {
"M",
"test 1",
"test 2",
"test 3",
"exit",
};
in this case, the first read attempt would run into IOException
, which is expected. However, subsequent reads fail with EndOfFileException
, I think subsequent reads should return test 1 , test 2, test 3, exit
, can you please take a look if this is an issue?
I'm not sure we want to go this way. The reason is that usually, streams exceptions are not recoverable, so we'll run a loop throwing an exception forever. This happens here: https://github.com/jline/jline3/blob/master/terminal/src/main/java/org/jline/terminal/impl/ExternalTerminal.java#L119-L141
When an exception is thrown by the underlying stream, the loop exits. If we catch the exception inside the loop, the loop will run forever, usually doing nothing but throwing / catching an exception. A good example is a socket stream : if the socket has been disconnected, you can't really recover from it. So maybe the current implementation is wrong, and the exception should be thrown after all the bytes already read have been consumed, but then always throw the exception and not reset it or throw an EOF.
the exception should be thrown after all the bytes already read have been consumed, but then always throw the exception and not reset it or throw an EOF.
I think in this case, the exact exception (be it IOException or any other exceptions) that the underlying stream encounters , rather than EOF, should be thrown to users over the LineReader.readLine()
API, it is up to the user to decide whether to retry reads upon receiving the exceptions, or stop reading.
As regard to reset exceptions, in my opinion, we could reset the exception. If we do not reset the exception, the user would hit the same exception repeatedly, he is not able to retry reads no matter the underlying stream is recoverable or not.
The problem is that the pump mechanism does not depend on the user, so it's not up to the user. do you have a use case where an InputStream can be correctly recovered after an IO exception ?
I do not have a real use case, the test above is to test out how jline API behaves in the scenario. I think some IOExceptions such as SocketTimeoutException
is transient and a retry read could succeed.
Do you think you could come up with a PR ?
ok, I'll look at the issue and try to create a PR.
Hi @gnodet ,
I tried with 3.7.1 snapshot (with your recent fix for #267), looks like there is an issue with IOException handling in the terminal implementation. Once the terminal throws an IOException, subsequent reads of
LineReader#readLine()
always hit that IOException, I think subsequent reads should succeed if they do not encounter any IOException. The test codes that reproduce the issue:Test output: