Skip to main content

EndpointError

Enum EndpointError 

Source
pub enum EndpointError {
Show 28 variants GoAwayUriAtServer, Session(SessionError), RequestId(RequestIdError), Subscription(SubscriptionError), Fetch(FetchError), Namespace(NamespaceError), TrackStatus(TrackStatusError), PublishFlow(PublishError), Setup(SetupError), UnknownRequest(u64), NotASubscription(u64), UpdateParameterNotForKind { request_id: u64, key: u64, }, NotActive, Draining, RepeatedGoAway, NotASubscribeNamespace(MessageType), NamespaceMessageOnControlStream(&'static str), ResponseIdMismatch { stream: u64, message: u64, }, DuplicateTrackAlias { alias: u64, established: u64, offered: u64, }, TrackAliasInUse { alias: u64, held: u64, }, ObjectPastFinalObject { alias: u64, group: u64, object: u64, final_group: u64, final_object: u64, }, UpdateForUnknownRequest(u64), UnjoinableSubscription { fetch: u64, joining: u64, }, WrongJoiningRefusal { fetch: u64, required: u64, }, UnknownPeerNamespace, PeerPrefixOverlap { request: u64, established: u64, }, OwnPrefixOverlap { established: u64, }, WrongOverlapRefusal { request: u64, required: u64, },
}
Expand description

Errors that can occur during endpoint operations.

Variants§

§

GoAwayUriAtServer

A GOAWAY carrying a New Session URI arrived at a server.

Section 9.4: “If a server receives a GOAWAY with a non-zero New Session URI Length it MUST close the session with a PROTOCOL_VIOLATION.” Migration is something a server offers a client, never the other way round.

§

Session(SessionError)

A session-level state machine error.

§

RequestId(RequestIdError)

A request ID allocation or validation error.

§

Subscription(SubscriptionError)

A subscription state machine error.

§

Fetch(FetchError)

A fetch state machine error.

§

Namespace(NamespaceError)

A namespace state machine error.

§

TrackStatus(TrackStatusError)

A track status state machine error.

§

PublishFlow(PublishError)

A publish flow state machine error.

§

Setup(SetupError)

A setup negotiation error.

§

UnknownRequest(u64)

The request ID does not match any known state machine.

§

NotASubscription(u64)

A message that only a subscription can carry named a track status.

Section 9.19 treats a TRACK_STATUS as a SUBSCRIBE “except it does not create downstream subscription state”, and says what follows from that in the same breath: “the subscriber cannot send REQUEST_UPDATE or UNSUBSCRIBE”. Both messages are about a subscription, and this request opened none for them to name.

Separate from EndpointError::UnknownRequest, which says the identifier names nothing at all. This one says it names something, and that what it names is the one request kind neither message applies to.

§

UpdateParameterNotForKind

A REQUEST_UPDATE carried a parameter that the kind of request it names does not admit.

Separate from a parameter REQUEST_UPDATE cannot carry at all, which is not an error: Section 9.2.2 says a parameter appearing in a message type it is not defined for is ignored. This one is defined for REQUEST_UPDATE and qualified by the request kind.

Fields

§request_id: u64

The Existing Request ID the update named.

§key: u64

The parameter type that the named request’s kind does not admit.

§

NotActive

The session is not in the Active state.

§

Draining

The session is draining and cannot accept new requests.

§

RepeatedGoAway

A second GOAWAY arrived on the control stream.

The GOAWAY that says the peer is going away is one message, and the draft answers a repeat of it with a session close rather than with an error about the second message: there is no state a second one could move that the first has not already moved.

§

NotASubscribeNamespace(MessageType)

A bidirectional stream the peer opened began with a message that is not a SUBSCRIBE_NAMESPACE.

Draft-16 Section 3.3: “This specification only specifies two uses of bidirectional streams, the control stream, which begins with CLIENT_SETUP, and SUBSCRIBE_NAMESPACE. Bidirectional streams MUST NOT begin with any other message type unless negotiated. If they do, the peer MUST close the Session with a Protocol Violation.”

The control stream is the client’s own first bidirectional stream, so of the two uses only one can ever arrive here.

§

NamespaceMessageOnControlStream(&'static str)

A NAMESPACE or NAMESPACE_DONE arrived on the control stream.

Both are answers to a SUBSCRIBE_NAMESPACE and both are placed on that request’s own stream. Section 9.21: NAMESPACE “is sent on the response stream of a SUBSCRIBE_NAMESPACE request”. Section 9.23: “All NAMESPACE_DONE messages are in response to a SUBSCRIBE_NAMESPACE, so only the namespace tuples after the ‘Track Namespace Prefix’ are included in the ‘Track Namespace Suffix’.”

Neither carries a Request ID — the suffix is relative to a prefix only the subscription knows — so on the control stream they name nothing at all. That is why this is a refusal rather than a message that could be handled anyway.

§

ResponseIdMismatch

A response arrived on a namespace subscription’s stream naming a different request than the stream carries.

Draft-16 puts the answer to a SUBSCRIBE_NAMESPACE “on the response half of the stream” (Section 9.25) and also gives REQUEST_OK and REQUEST_ERROR a Request ID field, so the request is named twice. When the two disagree the endpoint cannot tell which one the sender meant, and the draft says nothing about the case, so neither is acted on.

Fields

§stream: u64

The Request ID of the subscription whose stream it arrived on.

§message: u64

The Request ID the message itself carries.

§

DuplicateTrackAlias

The peer named a Track Alias it is already using for another track.

Draft-16 states it twice, once per message. Section 9.10: “The same Track Alias MUST NOT be used to refer to two different Tracks simultaneously. If a subscriber receives a SUBSCRIBE_OK that uses the same Track Alias as a different track with an Established subscription, it MUST close the session with error DUPLICATE_TRACK_ALIAS.” Section 9.13 is the same sentence with PUBLISH in place of SUBSCRIBE_OK.

The session is over: this endpoint’s own state has moved to Closed and the code the transport should close with is in EndpointError::session_error_code.

Fields

§alias: u64

The alias both tracks are named by.

§established: u64

The request whose live subscription holds the alias.

§offered: u64

The request whose message arrived naming it for another track.

§

TrackAliasInUse

This endpoint was asked to give a Track Alias to a second track.

The same rule as EndpointError::DuplicateTrackAlias read at the end that chooses the alias. Section 9.13 states it as a prohibition on the publisher before it states what the subscriber does about one: “The same Track Alias MUST NOT be used to refer to two different Tracks simultaneously.”

The message is refused instead of built, and nothing else moves: no Request ID is spent, no publish flow is created, and the session stays as it was. The alias never reaches the peer, so there is nothing for the peer to close over.

Fields

§alias: u64

The alias that is already spoken for.

§held: u64

The request whose live flow holds it.

§

ObjectPastFinalObject

An object arriving after the track’s final object.

Section 2.4.2 lists the condition: “An Object is received on a Track whose Group and Object ID are larger than the final Object in the Track. The final Object in a Track is the Object with Status END_OF_TRACK or the last Object sent in a FETCH whose response indicated End of Track.”

Larger is Section 1.4.1’s comparison and not a reading of the words. That section puts one Location below another when “A.Group < B.Group || (A.Group == B.Group && A.Object < B.Object)”, so an Object in a later group is past the end whatever its own Object ID is.

On this draft it is the only condition in that list this crate can detect, which is why the whole Malformed Track apparatus arrives with it rather than before it. The condition the drafts on either side are answered through — an object framed differently from the track’s earlier ones — is not a fault here: Section 10.2.1 says “Object Forwarding Preference is a property of an individual Object and can vary among Objects in the same Track”, so this draft keeps no per-track framing for an object to contradict. Draft-16 has stated the answer below since it was written and had nothing to answer it with.

A Malformed Track and not a session error. Section 2.4.2 answers its whole list at once, and on this draft that answer is “it MUST UNSUBSCRIBE any subscription and FETCH_CANCEL any fetch for that Track from that publisher”. The messages are the connection’s; this is the error half.

Fields

§alias: u64

The Track Alias the offending object named.

§group: u64

The Group ID it named.

§object: u64

The Object ID it named.

§final_group: u64

The Group ID of the object the track ended at.

§final_object: u64

The Object ID of the object the track ended at.

§

UpdateForUnknownRequest(u64)

REQUEST_UPDATE named a Request ID this session has never carried a request under.

Section 9.11: “The receiver MUST close the session with PROTOCOL_VIOLATION if the sender specifies an invalid Existing Request ID, or if the parameters included in the REQUEST_UPDATE are invalid for the type of request being modified.”

A request that has ended is not this: it existed. That is why the record of an inbound SUBSCRIBE outlives the subscription, and why an update naming an ended one is refused by the flow rather than by the session.

§

UnjoinableSubscription

A Joining Fetch named a subscription this session cannot join.

Section 9.16.2: “If a publisher receives a Joining Fetch with a Request ID that does not correspond to a subscription in the same session in the Established or Pending (subscriber) states, it MUST return a REQUEST_ERROR with error code INVALID_JOINING_REQUEST_ID.”

A refusal and not a session close, so the session runs on and the error names both identifiers: the fetch to refuse, and the subscription it asked to join.

Fields

§fetch: u64

The fetch that named it.

§joining: u64

The identifier it named.

§

WrongJoiningRefusal

A Joining Fetch was refused under a code other than the one the same sentence names for it.

The reason travels with the refusal, so a subscriber told the wrong one retries the wrong thing: it can rebuild a fetch whose range was refused, and cannot rebuild one whose subscription is gone.

Fields

§fetch: u64

The fetch being refused.

§required: u64

The code the draft names for that refusal.

§

UnknownPeerNamespace

A message about an announcement named a namespace the peer has not announced.

Section 9.24 says what a cancellation is for: the subscriber “will stop sending new subscriptions for tracks within the provided Track Namespace”. What a withdrawal ends and a cancellation revokes is an announcement the peer made, so the record they reach for is the one this endpoint keeps of the peer’s announcements.

Separate from EndpointError::UnknownRequest, which is how the same miss reads on the announcements this endpoint made: those are reached by the Request ID this endpoint allocated, and PUBLISH_NAMESPACE_DONE and PUBLISH_NAMESPACE_CANCEL both carry one.

§

PeerPrefixOverlap

The peer subscribed to a namespace prefix overlapping one it is already subscribed to.

Section 9.25: “A subscriber cannot make overlapping namespace subscriptions on a single session. Within a session, if a publisher receives a SUBSCRIBE_NAMESPACE with a Track Namespace Prefix that shares a common prefix with an established namespace subscription, it MUST respond with REQUEST_ERROR with error code PREFIX_OVERLAP.”

Taken when the message arrives, which is the moment the sentence names, and read again when an answer is built: a request this endpoint may not accept is one no later call can accept.

The refusal itself is not this error. It is a message the peer is owed, so the request is recorded like any other and refused through the same call that refuses any other, under the code the sentence names.

Fields

§request: u64

The request that arrived.

§established: u64

The namespace subscription it overlaps.

§

OwnPrefixOverlap

This endpoint was asked to subscribe to a namespace prefix overlapping one it is already subscribed to.

The first half of the same sentence, which is addressed to the subscriber: “A subscriber cannot make overlapping namespace subscriptions on a single session.”

The message is refused instead of built, and nothing else moves: no Request ID is spent, no state machine is created and the session stays as it was. The request never reaches the peer, so there is nothing for the peer to refuse.

Fields

§established: u64

The namespace subscription this endpoint already has.

§

WrongOverlapRefusal

A namespace subscription that overlaps another was refused under a code other than the one the sentence names.

The same shape as EndpointError::WrongJoiningRefusal: a rule that names the code its refusal carries is not satisfied by a refusal under any other, because the peer reads the code to learn what went wrong.

Fields

§request: u64

The request being refused.

§required: u64

The code the sentence names for it.

Implementations§

Source§

impl EndpointError

Source

pub fn session_error_code(&self) -> Option<SessionErrorCode>

The code to close the session with, when draft-16 answers this error with a close rather than leaving it to the one request it concerns.

None means the error is recoverable: the caller may report it, give up on the request it concerns, and keep the session running. Some means the draft ends the session, and the endpoint has already moved its own state to Closed - the code is what the transport should carry.

The table grows one rule at a time, and a rule joins it with a gate that drives the bytes at a real connection and reads the close code back off the wire. An arm added without one asserts nothing: from inside the process the session ends either way, and only the peer can tell the difference.

Trait Implementations§

Source§

impl Debug for EndpointError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for EndpointError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for EndpointError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<EndpointError> for ConnectionError

Source§

fn from(source: EndpointError) -> Self

Converts to this type from the input type.
Source§

impl From<FetchError> for EndpointError

Source§

fn from(source: FetchError) -> Self

Converts to this type from the input type.
Source§

impl From<NamespaceError> for EndpointError

Source§

fn from(source: NamespaceError) -> Self

Converts to this type from the input type.
Source§

impl From<PublishError> for EndpointError

Source§

fn from(source: PublishFlowError) -> Self

Converts to this type from the input type.
Source§

impl From<RequestIdError> for EndpointError

Source§

fn from(source: RequestIdError) -> Self

Converts to this type from the input type.
Source§

impl From<SessionError> for EndpointError

Source§

fn from(source: SessionError) -> Self

Converts to this type from the input type.
Source§

impl From<SetupError> for EndpointError

Source§

fn from(source: SetupError) -> Self

Converts to this type from the input type.
Source§

impl From<SubscriptionError> for EndpointError

Source§

fn from(source: SubscriptionError) -> Self

Converts to this type from the input type.
Source§

impl From<TrackStatusError> for EndpointError

Source§

fn from(source: TrackStatusError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more