Skip to content

Commit 3be4361

Browse files
authored
Close underlying stream after process failure in close (#182)
1 parent 710dff1 commit 3be4361

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

src/stream.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,14 @@ end
186186

187187
function Base.close(stream::TranscodingStream)
188188
mode = stream.state.mode
189-
if mode != :panic
190-
changemode!(stream, :close)
191-
end
192-
if !stream.state.stop_on_end
193-
close(stream.stream)
189+
try
190+
if mode != :panic
191+
changemode!(stream, :close)
192+
end
193+
finally
194+
if !stream.state.stop_on_end
195+
close(stream.stream)
196+
end
194197
end
195198
return nothing
196199
end

test/codecdoubleframe.jl

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,20 @@ function TranscodingStreams.process(
2626
codec :: DoubleFrameEncoder,
2727
input :: TranscodingStreams.Memory,
2828
output :: TranscodingStreams.Memory,
29-
error :: TranscodingStreams.Error,
29+
error_ref :: TranscodingStreams.Error,
3030
)
3131
if input.size == 0
3232
codec.got_stop_msg[] = true
3333
end
3434

3535
if output.size < 2
36-
error[] = ErrorException("requires a minimum of 2 bytes of output space")
36+
error_ref[] = ErrorException("requires a minimum of 2 bytes of output space")
3737
return 0, 0, :error
3838
elseif codec.stopped[]
39-
error[] = ErrorException("cannot process after stopped")
39+
error_ref[] = ErrorException("cannot process after stopped")
4040
return 0, 0, :error
4141
elseif codec.got_stop_msg[] && input.size != 0
42-
error[] = ErrorException("cannot accept more input after getting stop message")
42+
error_ref[] = ErrorException("cannot accept more input after getting stop message")
4343
return 0, 0, :error
4444
elseif !codec.opened[]
4545
output[1] = UInt8('[')
@@ -95,7 +95,7 @@ function TranscodingStreams.process(
9595
codec :: DoubleFrameDecoder,
9696
input :: TranscodingStreams.Memory,
9797
output :: TranscodingStreams.Memory,
98-
error :: TranscodingStreams.Error,
98+
error_ref :: TranscodingStreams.Error,
9999
)
100100
Δin::Int = 0
101101
Δout::Int = 0
@@ -167,7 +167,7 @@ function TranscodingStreams.process(
167167
catch e
168168
codec.state[]=7
169169
e isa ErrorException || rethrow()
170-
error[] = e
170+
error_ref[] = e
171171
return Δin, Δout, :error
172172
end
173173
end
@@ -243,6 +243,27 @@ DoubleFrameDecoderStream(stream::IO; kwargs...) = TranscodingStream(DoubleFrameD
243243
@test String(take!(sink)) == "[ ][ aabbcc ][ ddee ]"
244244
end
245245

246+
@testset "Issue #160 Safely close stream after failure" begin
247+
sink = IOBuffer()
248+
stream = TranscodingStream(DoubleFrameDecoder(), sink)
249+
write(stream, "abc")
250+
@test_throws ErrorException("expected [") close(stream)
251+
@test !isopen(stream)
252+
@test !isopen(sink)
253+
254+
@testset "nested decoders" begin
255+
sink = IOBuffer()
256+
stream = TranscodingStream(DoubleFrameDecoder(), sink)
257+
stream2 = TranscodingStream(DoubleFrameDecoder(), stream)
258+
write(stream2, "abc")
259+
# "expected byte" error with caused by "expected ["
260+
@test_throws ErrorException("expected byte") close(stream2)
261+
@test !isopen(stream2)
262+
@test !isopen(stream)
263+
@test !isopen(sink)
264+
end
265+
end
266+
246267
@testset "stop_on_end=true in nested streams" begin
247268
s1 = DoubleFrameDecoderStream(DoubleFrameEncoderStream(
248269
DoubleFrameDecoderStream(

0 commit comments

Comments
 (0)