Skip to content

Commit b34cf5a

Browse files
authored
handle errors in changestate! (#18)
1 parent 1f55bc3 commit b34cf5a

File tree

1 file changed

+23
-39
lines changed

1 file changed

+23
-39
lines changed

src/stream.jl

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -386,12 +386,12 @@ function fillbuffer(stream::TranscodingStream)
386386
# reset
387387
stream.state.code = startproc(stream.codec, :read, stream.state.error)
388388
if stream.state.code == :error
389-
handle_error(stream)
389+
changestate!(stream, :panic)
390390
end
391391
end
392392
makemargin!(buffer2, 1)
393393
readdata!(stream.stream, buffer2)
394-
_, Δout = call_process(stream.codec, stream.state, buffer2, buffer1)
394+
_, Δout = call_process(stream, buffer2, buffer1)
395395
nfilled += Δout
396396
end
397397
return nfilled
@@ -431,25 +431,26 @@ function process_to_write(stream::TranscodingStream)
431431
# reset
432432
stream.state.code = startproc(stream.codec, :write, stream.state.error)
433433
if stream.state.code == :error
434-
handle_error(stream)
434+
changestate!(stream, :panic)
435435
end
436436
end
437437
buffer2 = stream.state.buffer2
438438
writebuffer!(stream.stream, buffer2)
439-
Δin, _ = call_process(stream.codec, stream.state, buffer1, buffer2)
439+
Δin, _ = call_process(stream, buffer1, buffer2)
440440
makemargin!(buffer1, 0)
441441
return Δin
442442
end
443443

444-
function call_process(codec::Codec, state::State, inbuf::Buffer, outbuf::Buffer)
444+
function call_process(stream::TranscodingStream, inbuf::Buffer, outbuf::Buffer)
445+
state = stream.state
445446
input = buffermem(inbuf)
446-
makemargin!(outbuf, minoutsize(codec, input))
447-
Δin, Δout, state.code = process(codec, input, marginmem(outbuf), state.error)
447+
makemargin!(outbuf, minoutsize(stream.codec, input))
448+
Δin, Δout, state.code = process(stream.codec, input, marginmem(outbuf), state.error)
448449
inbuf.bufferpos += Δin
449450
outbuf.marginpos += Δout
450451
outbuf.total += Δout
451452
if state.code == :error
452-
handle_error(codec, state)
453+
changestate!(stream, :panic)
453454
elseif state.code == :ok && Δin == Δout == 0
454455
# When no progress, expand the output buffer.
455456
makemargin!(outbuf, max(16, marginsize(outbuf) * 2))
@@ -471,16 +472,25 @@ function changestate!(stream::TranscodingStream, newstate::Symbol)
471472
if state == newstate
472473
# state does not change
473474
return
475+
elseif newstate == :panic
476+
if !haserror(stream.state.error)
477+
# set a default error
478+
stream.state.error[] = ErrorException("unknown error happened while processing data")
479+
end
480+
stream.state.state = newstate
481+
finalize_codec(stream.codec, stream.state.error)
482+
throw(stream.state.error[])
474483
elseif state == :idle
475484
if newstate == :read || newstate == :write
476485
stream.state.code = startproc(stream.codec, newstate, stream.state.error)
477486
if stream.state.code == :error
478-
handle_error(stream)
487+
changestate!(stream, :panic)
479488
end
480489
stream.state.state = newstate
481490
return
482491
elseif newstate == :close
483-
finalize_codec(stream, :close)
492+
stream.state.state = newstate
493+
finalize_codec(stream.codec, stream.state.error)
484494
return
485495
end
486496
elseif state == :read
@@ -530,41 +540,15 @@ function throw_panic_error()
530540
throw(ArgumentError("stream is in unrecoverable error; only isopen and close are callable"))
531541
end
532542

533-
534-
# Error Handler
535-
# -------------
536-
537-
# Handle an error happened while transcoding data.
538-
function handle_error(stream::TranscodingStream)
539-
handle_error(stream.codec, stream.state)
540-
end
541-
542-
function handle_error(codec::Codec, state::State)
543-
if !haserror(state.error)
544-
# set a generic error
545-
state.error[] = ErrorException("unknown error happened while processing data")
546-
end
547-
finalize_codec(codec, state, :panic)
548-
throw(state.error[])
549-
end
550-
551543
# Call the finalize method of the codec.
552-
function finalize_codec(stream::TranscodingStream, newstate::Symbol)
553-
finalize_codec(stream.codec, stream.state, newstate)
554-
end
555-
556-
function finalize_codec(codec::Codec, state::State, newstate::Symbol)
557-
@assert newstate (:close, :panic)
544+
function finalize_codec(codec::Codec, error::Error)
558545
try
559546
finalize(codec)
560547
catch
561-
if state.state == :error && haserror(state.error)
562-
# throw an exception that happended before
563-
throw(state.error[])
548+
if haserror(error)
549+
throw(error[])
564550
else
565551
rethrow()
566552
end
567-
finally
568-
state.state = newstate
569553
end
570554
end

0 commit comments

Comments
 (0)