API-Docker

 view release on metacpan or  search on metacpan

lib/API/Docker/Error/Truncated.pm  view on Meta::CPAN

C<No response from Docker daemon> croak it has always been -- there is no
half-sent response to describe, and that string predates every error class
here.

A response with a status of 400 or above raises this rather than
L<API::Docker::Error::HTTP> when B<its> body is the one cut short, which is
the same rule the timeout follows: the transport cannot tell a caller what the
engine said when it did not finish saying it. Read L</partial> for the part of
the error body that did arrive.

=head2 It is still the string it replaces

Like the other three error classes here, this one overloads stringification
(with C<< fallback => 1 >>, so comparison, concatenation, C<sprintf> and
matching all work through it) and produces what a plain C<croak> would have
died with: the reason, followed by Carp's own C< at FILE line N.> location
suffix, naming the same frame.

Unlike the other three it replaces no string, because there was nothing here
to replace -- a truncated response used to be returned rather than raised.
That makes it the one exception in this distribution that existing code cannot
have been catching, which is why it is a documented behaviour change and not a
bug fix in passing.

The boolean overload is explicit rather than derived from the string, so it
cannot be made false by its own message.

=head2 message

The reason on its own, without the location suffix: the request it belongs to,
where in the response framing the stream ended, and how much had arrived.

The request is named without its query string, for the same reason the
C<< >= 400 >> croak names it that way -- C</build> carries its C<buildargs>
there, which can hold credentials and have no business in an exception.

=head2 location

Carp's location suffix (C< at FILE line N.\n>), captured at the point the
error was raised so it names the same frame a plain C<croak> would have named.
Kept apart from L</message> so a caller can have the reason without it.

=head2 endpoint

The request that was cut short, as C<"GET /v1.47/images/get"> -- method and
path, no query string. The empty string for a reader driven directly with no
request context, which is how the transport's own tests drive them.

=head2 phase

Which piece of the response framing the stream ended inside. One of:

=over

=item * C<'status-line'> - the stream ended inside the status line, before the
CRLF that terminates it. A status line with nothing after it parses perfectly
well -- C<'HTTP/1.1 200 OK'> yields 200 and C<OK> -- so the missing terminator
is the only thing that says the daemon never finished writing it. Also a line
that arrived in full but is not an HTTP status line at all -- a proxy's
plain-text banner, an HTML error page -- which is no cut response, but is
refused here for the reason the non-hexadecimal chunk size below is: its second
word would otherwise be split out and read as the status

=item * C<'header-block'> - the stream ended inside a header line, or where
one belongs with the blank line that ends the field section never sent. The
second covers a head with no fields at all: RFC 9112 section 2.1 requires the
empty line whether there are twenty fields or none

=item * C<'content-length'> - fewer bytes arrived than the C<Content-Length>
header announced, or the header arrived in full but its value is not a number.
The second is no cut response either: left as it stood it would read as C<0>
and a response that had a body would come back empty, the same body-shaped lie
a truncation is

=item * C<'chunk-header'> - the stream ended inside a chunk size line, or at a
chunk boundary with no terminating zero chunk after it, or a chunk size line
that arrived in full but is not a hexadecimal number. The last is not a cut
response: the line is complete and terminated, but C<hex> would read its
garbage as C<0> -- the terminating zero chunk -- so the body would silently
come back empty. It is caught here because the outcome is the same body-shaped
lie a truncation is, not because the connection went away

=item * C<'chunk-data'> - the stream ended inside a chunk, short of the size
that chunk's own header announced

=item * C<'chunk-terminator'> - a chunk's data arrived in full and the CRLF
that ends it did not

=back

Informational rather than something to branch on: every value means the same
thing to a caller, which is that the response is incomplete. It is here
because "which of the four" is the first question when a real engine starts
raising this, and reading it off the object beats parsing L</message>.

=head2 expected

The byte count the framing announced for the piece that was cut short: the
C<Content-Length> for C<'content-length'>, the chunk's own size for
C<'chunk-data'>. C<undef> for the four phases with no announcement to fall
short of, which are the ones framed by a terminator instead.

=head2 received

How many of L</expected> arrived. C<undef> whenever L</expected> is.

Note that this counts the piece, not the response: on a chunked body it is the
bytes of the unfinished chunk, while L</partial> holds every chunk before it
as well.

=head2 partial

The response body bytes that had arrived when the stream ended, for a request
whose body was being buffered -- the empty string when none had.

These are B<not> a body: nothing was decoded, no chunk framing was verified
beyond what was needed to find the truncation, and the content stops
mid-value. They are here so a caller who wants them can have them rather than
because the transport thinks they are usable.

Always the empty string for a streamed request, which keeps no body by design.
Nothing is lost there either: every byte that arrived went through the same
decoding as every other byte, so the units it completed reached the callback
and are counted in L</summary> before this is raised.

Also always the empty string when L</phase> is C<'status-line'> or
C<'header-block'>: the response was cut before its body began, so there are no
body bytes to hand over. The bytes of the head itself are deliberately not put
here -- they are not a body, and L</message> already says how far into which
piece the stream got.



( run in 3.216 seconds using v1.01-cache-2.11-cpan-d01c6094234 )