#[non_exhaustive]pub enum SseError<E> {
Transport(E),
InvalidUtf8(Utf8Error),
#[non_exhaustive] EventTooLarge {
limit: usize,
},
}Expand description
Why an SseStream (or an SseDecoder, with E =
Infallible) failed.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Transport(E)
Reading the body failed: the body stream’s own error. Map it as you
would any mid-stream transport failure (a
TransportError keeps its kind, so a
stream timeout stays a timeout).
InvalidUtf8(Utf8Error)
A line was not valid UTF-8.
The WHATWG event stream format decodes the stream as UTF-8 and
replaces invalid bytes with U+FFFD. This decoder fails instead, on
purpose. A browser shows event text to a person; an adapter decodes
JSON from it, and a replaced byte changes a string value (generated
text, tool arguments, an opaque signature that is replayed later)
without anything saying so, which allama never does silently (ADR
0003). Invalid UTF-8 means a broken server or intermediary, and
asking again streams the same bytes: map it to a stream decode
error (allama::Error::stream_decode), which is not retryable,
not to a transport failure. A chunk boundary inside a UTF-8
sequence is not an error: each line is decoded once it is complete.
#[non_exhaustive]EventTooLarge
A line, or an event’s data, passed the decoder’s size cap
(SseDecoder::max_event_size). The stream is not one the caller
is prepared to hold, and asking again gets the same answer: map it
to a stream protocol error (allama::Error::stream_protocol),
not a retryable transport failure.
Implementations§
Source§impl<E: Into<TransportError>> SseError<E>
impl<E: Into<TransportError>> SseError<E>
Sourcepub fn into_error(self) -> Error
pub fn into_error(self) -> Error
The portable error for a failed SSE stream, as the variants say:
Transport: the body error as aTransportError, mapped byTransportError::into_stream_error, so a stream timeout staysallama::Error::Timeoutand any other failed read is a retryable transport stream error, with the transport’s text as the upstream message;InvalidUtf8: a stream decode error;EventTooLarge: a stream protocol error.
Neither of the last two is retryable, and every message is
authored. Add the provider and the request
id. SseChatStream::new maps failures with it.
use allama::{Error, StreamErrorKind};
use allama_http::sse::{SseError, SseStream};
use allama_http::{TransportError, TransportErrorKind};
use futures_util::{FutureExt, StreamExt, stream};
let body = stream::iter([Ok::<_, TransportError>(&b"data: \xFF\n\n"[..])]);
let failure = SseStream::new(body).next().now_or_never().flatten().unwrap().unwrap_err();
let err = failure.into_error().with_provider("acme");
assert!(matches!(err, Error::Stream { kind: StreamErrorKind::Decode, .. }));
assert!(!err.is_retryable());
let timeout = SseError::Transport(TransportError::new(TransportErrorKind::Timeout, "idle"));
assert!(matches!(timeout.into_error(), Error::Timeout { .. }));Trait Implementations§
impl<E: Eq> Eq for SseError<E>
Source§impl<E: Error + 'static> Error for SseError<E>
impl<E: Error + 'static> Error for SseError<E>
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
A transport failure is transparent: its source is the body error’s source.
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl<E: Into<TransportError>> From<SseError<E>> for Error
impl<E: Into<TransportError>> From<SseError<E>> for Error
Source§fn from(error: SseError<E>) -> Self
fn from(error: SseError<E>) -> Self
The error SseError::into_error gives: what
FramedChatStream::new
classifies a failure with.
impl<E: PartialEq> StructuralPartialEq for SseError<E>
Auto Trait Implementations§
impl<E> Freeze for SseError<E>where
E: Freeze,
impl<E> RefUnwindSafe for SseError<E>where
E: RefUnwindSafe,
impl<E> Send for SseError<E>where
E: Send,
impl<E> Sync for SseError<E>where
E: Sync,
impl<E> Unpin for SseError<E>where
E: Unpin,
impl<E> UnsafeUnpin for SseError<E>where
E: UnsafeUnpin,
impl<E> UnwindSafe for SseError<E>where
E: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.