webrtc/
error.rs

1use std::future::Future;
2use std::num::ParseIntError;
3use std::pin::Pin;
4use std::string::FromUtf8Error;
5
6use thiserror::Error;
7use tokio::sync::mpsc::error::SendError as MpscSendError;
8
9use crate::peer_connection::sdp::sdp_type::RTCSdpType;
10use crate::peer_connection::signaling_state::RTCSignalingState;
11use crate::rtp_transceiver::rtp_receiver;
12#[cfg(doc)]
13use crate::rtp_transceiver::rtp_sender;
14
15pub type Result<T> = std::result::Result<T, Error>;
16
17#[derive(Error, Debug, PartialEq)]
18#[non_exhaustive]
19pub enum Error {
20    /// ErrUnknownType indicates an error with Unknown info.
21    #[error("unknown")]
22    ErrUnknownType,
23
24    /// ErrConnectionClosed indicates an operation executed after connection
25    /// has already been closed.
26    #[error("connection closed")]
27    ErrConnectionClosed,
28
29    /// ErrDataChannelNotOpen indicates an operation executed when the data
30    /// channel is not (yet) open.
31    #[error("data channel not open")]
32    ErrDataChannelNotOpen,
33
34    /// ErrCertificateExpired indicates that an x509 certificate has expired.
35    #[error("x509Cert expired")]
36    ErrCertificateExpired,
37
38    /// ErrNoTurnCredentials indicates that a TURN server URL was provided
39    /// without required credentials.
40    #[error("turn server credentials required")]
41    ErrNoTurnCredentials,
42
43    /// ErrExistingTrack indicates that a track already exists.
44    #[error("track already exists")]
45    ErrExistingTrack,
46
47    /// ErrPrivateKeyType indicates that a particular private key encryption
48    /// chosen to generate a certificate is not supported.
49    #[error("private key type not supported")]
50    ErrPrivateKeyType,
51
52    /// ErrModifyingPeerIdentity indicates that an attempt to modify
53    /// PeerIdentity was made after PeerConnection has been initialized.
54    #[error("peerIdentity cannot be modified")]
55    ErrModifyingPeerIdentity,
56
57    /// ErrModifyingCertificates indicates that an attempt to modify
58    /// Certificates was made after PeerConnection has been initialized.
59    #[error("certificates cannot be modified")]
60    ErrModifyingCertificates,
61
62    /// ErrNonCertificate indicates that there is no certificate
63    #[error("no certificate")]
64    ErrNonCertificate,
65
66    /// ErrModifyingBundlePolicy indicates that an attempt to modify
67    /// BundlePolicy was made after PeerConnection has been initialized.
68    #[error("bundle policy cannot be modified")]
69    ErrModifyingBundlePolicy,
70
71    /// ErrModifyingRTCPMuxPolicy indicates that an attempt to modify
72    /// RTCPMuxPolicy was made after PeerConnection has been initialized.
73    #[error("rtcp mux policy cannot be modified")]
74    ErrModifyingRTCPMuxPolicy,
75
76    /// ErrModifyingICECandidatePoolSize indicates that an attempt to modify
77    /// ICECandidatePoolSize was made after PeerConnection has been initialized.
78    #[error("ice candidate pool size cannot be modified")]
79    ErrModifyingICECandidatePoolSize,
80
81    /// ErrStringSizeLimit indicates that the character size limit of string is
82    /// exceeded. The limit is hardcoded to 65535 according to specifications.
83    #[error("data channel label exceeds size limit")]
84    ErrStringSizeLimit,
85
86    /// ErrMaxDataChannelID indicates that the maximum number ID that could be
87    /// specified for a data channel has been exceeded.
88    #[error("maximum number ID for datachannel specified")]
89    ErrMaxDataChannelID,
90
91    /// ErrNegotiatedWithoutID indicates that an attempt to create a data channel
92    /// was made while setting the negotiated option to true without providing
93    /// the negotiated channel ID.
94    #[error("negotiated set without channel id")]
95    ErrNegotiatedWithoutID,
96
97    /// ErrRetransmitsOrPacketLifeTime indicates that an attempt to create a data
98    /// channel was made with both options max_packet_life_time and max_retransmits
99    /// set together. Such configuration is not supported by the specification
100    /// and is mutually exclusive.
101    #[error("both max_packet_life_time and max_retransmits was set")]
102    ErrRetransmitsOrPacketLifeTime,
103
104    /// ErrCodecNotFound is returned when a codec search to the Media Engine fails
105    #[error("codec not found")]
106    ErrCodecNotFound,
107
108    /// ErrNoRemoteDescription indicates that an operation was rejected because
109    /// the remote description is not set
110    #[error("remote description is not set")]
111    ErrNoRemoteDescription,
112
113    /// ErrIncorrectSDPSemantics indicates that the PeerConnection was configured to
114    /// generate SDP Answers with different SDP Semantics than the received Offer
115    #[error("offer SDP semantics does not match configuration")]
116    ErrIncorrectSDPSemantics,
117
118    /// ErrIncorrectSignalingState indicates that the signaling state of PeerConnection is not correct
119    #[error("operation can not be run in current signaling state")]
120    ErrIncorrectSignalingState,
121
122    /// ErrProtocolTooLarge indicates that value given for a DataChannelInit protocol is
123    /// longer then 65535 bytes
124    #[error("protocol is larger then 65535 bytes")]
125    ErrProtocolTooLarge,
126
127    /// ErrSenderNotCreatedByConnection indicates remove_track was called with a
128    /// [`rtp_sender::RTCRtpSender`] not created by this PeerConnection
129    #[error("RtpSender not created by this PeerConnection")]
130    ErrSenderNotCreatedByConnection,
131
132    /// ErrSenderInitialTrackIdAlreadySet indicates a second call to
133    /// `RTCRtpSender::set_initial_track_id` which is not allowed. Purely internal error, should not happen in practice.
134    #[error("RtpSender's initial_track_id has already been set")]
135    ErrSenderInitialTrackIdAlreadySet,
136
137    /// ErrSessionDescriptionNoFingerprint indicates set_remote_description was called with a SessionDescription that has no
138    /// fingerprint
139    #[error("set_remote_description called with no fingerprint")]
140    ErrSessionDescriptionNoFingerprint,
141
142    /// ErrSessionDescriptionInvalidFingerprint indicates set_remote_description was called with a SessionDescription that
143    /// has an invalid fingerprint
144    #[error("set_remote_description called with an invalid fingerprint")]
145    ErrSessionDescriptionInvalidFingerprint,
146
147    /// ErrSessionDescriptionConflictingFingerprints indicates set_remote_description was called with a SessionDescription that
148    /// has an conflicting fingerprints
149    #[error("set_remote_description called with multiple conflicting fingerprint")]
150    ErrSessionDescriptionConflictingFingerprints,
151
152    /// ErrSessionDescriptionMissingIceUfrag indicates set_remote_description was called with a SessionDescription that
153    /// is missing an ice-ufrag value
154    #[error("set_remote_description called with no ice-ufrag")]
155    ErrSessionDescriptionMissingIceUfrag,
156
157    /// ErrSessionDescriptionMissingIcePwd indicates set_remote_description was called with a SessionDescription that
158    /// is missing an ice-pwd value
159    #[error("set_remote_description called with no ice-pwd")]
160    ErrSessionDescriptionMissingIcePwd,
161
162    /// ErrSessionDescriptionConflictingIceUfrag  indicates set_remote_description was called with a SessionDescription that
163    /// contains multiple conflicting ice-ufrag values
164    #[error("set_remote_description called with multiple conflicting ice-ufrag values")]
165    ErrSessionDescriptionConflictingIceUfrag,
166
167    /// ErrSessionDescriptionConflictingIcePwd indicates set_remote_description was called with a SessionDescription that
168    /// contains multiple conflicting ice-pwd values
169    #[error("set_remote_description called with multiple conflicting ice-pwd values")]
170    ErrSessionDescriptionConflictingIcePwd,
171
172    /// ErrNoSRTPProtectionProfile indicates that the DTLS handshake completed and no SRTP Protection Profile was chosen
173    #[error("DTLS Handshake completed and no SRTP Protection Profile was chosen")]
174    ErrNoSRTPProtectionProfile,
175
176    /// ErrFailedToGenerateCertificateFingerprint indicates that we failed to generate the fingerprint used for comparing certificates
177    #[error("failed to generate certificate fingerprint")]
178    ErrFailedToGenerateCertificateFingerprint,
179
180    /// ErrNoCodecsAvailable indicates that operation isn't possible because the MediaEngine has no codecs available
181    #[error("operation failed no codecs are available")]
182    ErrNoCodecsAvailable,
183
184    /// ErrUnsupportedCodec indicates the remote peer doesn't support the requested codec
185    #[error("unable to start track, codec is not supported by remote")]
186    ErrUnsupportedCodec,
187
188    /// ErrSenderWithNoCodecs indicates that a RTPSender was created without any codecs. To send media the MediaEngine needs at
189    /// least one configured codec.
190    #[error("unable to populate media section, RTPSender created with no codecs")]
191    ErrSenderWithNoCodecs,
192
193    /// ErrRTPSenderNewTrackHasIncorrectKind indicates that the new track is of a different kind than the previous/original
194    #[error("new track must be of the same kind as previous")]
195    ErrRTPSenderNewTrackHasIncorrectKind,
196
197    /// ErrRTPSenderNewTrackHasIncorrectEnvelope indicates that the new track has a different envelope than the previous/original
198    #[error("new track must have the same envelope as previous")]
199    ErrRTPSenderNewTrackHasIncorrectEnvelope,
200
201    /// ErrRTPSenderDataSent indicates that the sequence number transformer tries to be enabled after the data sending began
202    #[error("Sequence number transformer must be enabled before sending data")]
203    ErrRTPSenderDataSent,
204
205    /// ErrRTPSenderSeqTransEnabled indicates that the sequence number transformer has been already enabled
206    #[error("Sequence number transformer has been already enabled")]
207    ErrRTPSenderSeqTransEnabled,
208
209    /// ErrUnbindFailed indicates that a TrackLocal was not able to be unbind
210    #[error("failed to unbind TrackLocal from PeerConnection")]
211    ErrUnbindFailed,
212
213    /// ErrNoPayloaderForCodec indicates that the requested codec does not have a payloader
214    #[error("the requested codec does not have a payloader")]
215    ErrNoPayloaderForCodec,
216
217    /// ErrRegisterHeaderExtensionInvalidDirection indicates that a extension was registered with different
218    /// directions for two different calls.
219    #[error("a header extension must be registered with the same direction each time")]
220    ErrRegisterHeaderExtensionInvalidDirection,
221
222    /// ErrRegisterHeaderExtensionNoFreeID indicates that there was no extension ID available which
223    /// in turn means that all 15 available id(1 through 14) have been used.
224    #[error("no header extension ID was free to use(this means the maximum of 15 extensions have been registered)")]
225    ErrRegisterHeaderExtensionNoFreeID,
226
227    /// ErrSimulcastProbeOverflow indicates that too many Simulcast probe streams are in flight and the requested SSRC was ignored
228    #[error("simulcast probe limit has been reached, new SSRC has been discarded")]
229    ErrSimulcastProbeOverflow,
230
231    #[error("enable detaching by calling webrtc.DetachDataChannels()")]
232    ErrDetachNotEnabled,
233    #[error("datachannel not opened yet, try calling Detach from OnOpen")]
234    ErrDetachBeforeOpened,
235    #[error("the DTLS transport has not started yet")]
236    ErrDtlsTransportNotStarted,
237    #[error("failed extracting keys from DTLS for SRTP")]
238    ErrDtlsKeyExtractionFailed,
239    #[error("failed to start SRTP")]
240    ErrFailedToStartSRTP,
241    #[error("failed to start SRTCP")]
242    ErrFailedToStartSRTCP,
243    #[error("attempted to start DTLSTransport that is not in new state")]
244    ErrInvalidDTLSStart,
245    #[error("peer didn't provide certificate via DTLS")]
246    ErrNoRemoteCertificate,
247    #[error("identity provider is not implemented")]
248    ErrIdentityProviderNotImplemented,
249    #[error("remote certificate does not match any fingerprint")]
250    ErrNoMatchingCertificateFingerprint,
251    #[error("unsupported fingerprint algorithm")]
252    ErrUnsupportedFingerprintAlgorithm,
253    #[error("ICE connection not started")]
254    ErrICEConnectionNotStarted,
255    #[error("unknown candidate type")]
256    ErrICECandidateTypeUnknown,
257    #[error("cannot convert ice.CandidateType into webrtc.ICECandidateType, invalid type")]
258    ErrICEInvalidConvertCandidateType,
259    #[error("ICEAgent does not exist")]
260    ErrICEAgentNotExist,
261    #[error("unable to convert ICE candidates to ICECandidates")]
262    ErrICECandidatesConversionFailed,
263    #[error("unknown ICE Role")]
264    ErrICERoleUnknown,
265    #[error("unknown protocol")]
266    ErrICEProtocolUnknown,
267    #[error("gatherer not started")]
268    ErrICEGathererNotStarted,
269    #[error("unknown network type")]
270    ErrNetworkTypeUnknown,
271    #[error("new sdp does not match previous offer")]
272    ErrSDPDoesNotMatchOffer,
273    #[error("new sdp does not match previous answer")]
274    ErrSDPDoesNotMatchAnswer,
275    #[error("provided value is not a valid enum value of type SDPType")]
276    ErrPeerConnSDPTypeInvalidValue,
277    #[error("invalid state change op")]
278    ErrPeerConnStateChangeInvalid,
279    #[error("unhandled state change op")]
280    ErrPeerConnStateChangeUnhandled,
281    #[error("invalid SDP type supplied to SetLocalDescription()")]
282    ErrPeerConnSDPTypeInvalidValueSetLocalDescription,
283    #[error("remoteDescription contained media section without mid value")]
284    ErrPeerConnRemoteDescriptionWithoutMidValue,
285    #[error("remoteDescription has not been set yet")]
286    ErrPeerConnRemoteDescriptionNil,
287    #[error("single media section has an explicit SSRC")]
288    ErrPeerConnSingleMediaSectionHasExplicitSSRC,
289    #[error("could not add transceiver for remote SSRC")]
290    ErrPeerConnRemoteSSRCAddTransceiver,
291    #[error("mid RTP Extensions required for Simulcast")]
292    ErrPeerConnSimulcastMidRTPExtensionRequired,
293    #[error("stream id RTP Extensions required for Simulcast")]
294    ErrPeerConnSimulcastStreamIDRTPExtensionRequired,
295    #[error("incoming SSRC failed Simulcast probing")]
296    ErrPeerConnSimulcastIncomingSSRCFailed,
297    #[error("failed collecting stats")]
298    ErrPeerConnStatsCollectionFailed,
299    #[error("add_transceiver_from_kind only accepts one RTPTransceiverInit")]
300    ErrPeerConnAddTransceiverFromKindOnlyAcceptsOne,
301    #[error("add_transceiver_from_track only accepts one RTPTransceiverInit")]
302    ErrPeerConnAddTransceiverFromTrackOnlyAcceptsOne,
303    #[error("add_transceiver_from_kind currently only supports recvonly")]
304    ErrPeerConnAddTransceiverFromKindSupport,
305    #[error("add_transceiver_from_track currently only supports sendonly and sendrecv")]
306    ErrPeerConnAddTransceiverFromTrackSupport,
307    #[error("TODO set_identity_provider")]
308    ErrPeerConnSetIdentityProviderNotImplemented,
309    #[error("write_rtcp failed to open write_stream")]
310    ErrPeerConnWriteRTCPOpenWriteStream,
311    #[error("cannot find transceiver with mid")]
312    ErrPeerConnTransceiverMidNil,
313    #[error("DTLSTransport must not be nil")]
314    ErrRTPReceiverDTLSTransportNil,
315    #[error("Receive has already been called")]
316    ErrRTPReceiverReceiveAlreadyCalled,
317    #[error("unable to find stream for Track with SSRC")]
318    ErrRTPReceiverWithSSRCTrackStreamNotFound,
319    #[error("no trackStreams found for SSRC")]
320    ErrRTPReceiverForSSRCTrackStreamNotFound,
321    #[error("no trackStreams found for RID")]
322    ErrRTPReceiverForRIDTrackStreamNotFound,
323    #[error("invalid RTP Receiver transition from {from} to {to}")]
324    ErrRTPReceiverStateChangeInvalid {
325        from: rtp_receiver::State,
326        to: rtp_receiver::State,
327    },
328    #[error("Track must not be nil")]
329    ErrRTPSenderTrackNil,
330    #[error("Sender has already been stopped")]
331    ErrRTPSenderStopped,
332    #[error("Sender Track has been removed or replaced to nil")]
333    ErrRTPSenderTrackRemoved,
334    #[error("Sender cannot add encoding as rid is empty")]
335    ErrRTPSenderRidNil,
336    #[error("Sender cannot add encoding as there is no base track")]
337    ErrRTPSenderNoBaseEncoding,
338    #[error("Sender cannot add encoding as provided track does not match base track")]
339    ErrRTPSenderBaseEncodingMismatch,
340    #[error("Sender cannot encoding due to RID collision")]
341    ErrRTPSenderRIDCollision,
342    #[error("Sender does not have track for RID")]
343    ErrRTPSenderNoTrackForRID,
344    #[error("RTPSender must not be nil")]
345    ErrRTPSenderNil,
346    #[error("RTPReceiver must not be nil")]
347    ErrRTPReceiverNil,
348    #[error("DTLSTransport must not be nil")]
349    ErrRTPSenderDTLSTransportNil,
350    #[error("Send has already been called")]
351    ErrRTPSenderSendAlreadyCalled,
352    #[error("errRTPSenderTrackNil")]
353    ErrRTPTransceiverCannotChangeMid,
354    #[error("invalid state change in RTPTransceiver.setSending")]
355    ErrRTPTransceiverSetSendingInvalidState,
356    #[error("unsupported codec type by this transceiver")]
357    ErrRTPTransceiverCodecUnsupported,
358    #[error("DTLS not established")]
359    ErrSCTPTransportDTLS,
360    #[error("add_transceiver_sdp() called with 0 transceivers")]
361    ErrSDPZeroTransceivers,
362    #[error("invalid Media Section. Media + DataChannel both enabled")]
363    ErrSDPMediaSectionMediaDataChanInvalid,
364    #[error(
365        "invalid Media Section. Can not have multiple tracks in one MediaSection in UnifiedPlan"
366    )]
367    ErrSDPMediaSectionMultipleTrackInvalid,
368    #[error("set_answering_dtlsrole must DTLSRoleClient or DTLSRoleServer")]
369    ErrSettingEngineSetAnsweringDTLSRole,
370    #[error("can't rollback from stable state")]
371    ErrSignalingStateCannotRollback,
372    #[error(
373        "invalid proposed signaling state transition from {} applying {} {}",
374        from,
375        if *is_local { "local" } else {  "remote" },
376        applying
377    )]
378    ErrSignalingStateProposedTransitionInvalid {
379        from: RTCSignalingState,
380        applying: RTCSdpType,
381        is_local: bool,
382    },
383    #[error("cannot convert to StatsICECandidatePairStateSucceeded invalid ice candidate state")]
384    ErrStatsICECandidateStateInvalid,
385    #[error("ICETransport can only be called in ICETransportStateNew")]
386    ErrICETransportNotInNew,
387    #[error("bad Certificate PEM format")]
388    ErrCertificatePEMFormatError,
389    #[error("SCTP is not established")]
390    ErrSCTPNotEstablished,
391
392    #[error("DataChannel is not opened")]
393    ErrClosedPipe,
394    #[error("Interceptor is not bind")]
395    ErrInterceptorNotBind,
396    #[error("excessive retries in CreateOffer")]
397    ErrExcessiveRetries,
398
399    #[error("not long enough to be a RTP Packet")]
400    ErrRTPTooShort,
401
402    #[error("{0}")]
403    Util(#[from] util::Error),
404    #[error("{0}")]
405    Ice(#[from] ice::Error),
406    #[error("{0}")]
407    Srtp(#[from] srtp::Error),
408    #[error("{0}")]
409    Dtls(#[from] dtls::Error),
410    #[error("{0}")]
411    Data(#[from] data::Error),
412    #[error("{0}")]
413    Sctp(#[from] sctp::Error),
414    #[error("{0}")]
415    Sdp(#[from] sdp::Error),
416    #[error("{0}")]
417    Interceptor(#[from] interceptor::Error),
418    #[error("{0}")]
419    Rtcp(#[from] rtcp::Error),
420    #[error("{0}")]
421    Rtp(#[from] rtp::Error),
422
423    #[error("utf-8 error: {0}")]
424    Utf8(#[from] FromUtf8Error),
425    #[error("{0}")]
426    RcGen(#[from] rcgen::Error),
427    #[error("mpsc send: {0}")]
428    MpscSend(String),
429    #[error("parse int: {0}")]
430    ParseInt(#[from] ParseIntError),
431    #[error("parse url: {0}")]
432    ParseUrl(#[from] url::ParseError),
433
434    /// Error parsing a given PEM string.
435    #[error("invalid PEM: {0}")]
436    InvalidPEM(String),
437
438    #[allow(non_camel_case_types)]
439    #[error("{0}")]
440    new(String),
441}
442
443pub type OnErrorHdlrFn =
444    Box<dyn (FnMut(Error) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>) + Send + Sync>;
445
446// Because Tokio SendError is parameterized, we sadly lose the backtrace.
447impl<T> From<MpscSendError<T>> for Error {
448    fn from(e: MpscSendError<T>) -> Self {
449        Error::MpscSend(e.to_string())
450    }
451}
452
453impl From<Error> for interceptor::Error {
454    fn from(e: Error) -> Self {
455        // this is a bit lol, but we do preserve the stack trace
456        interceptor::Error::Util(util::Error::from_std(e))
457    }
458}
459
460impl PartialEq<ice::Error> for Error {
461    fn eq(&self, other: &ice::Error) -> bool {
462        if let Error::Ice(e) = self {
463            return e == other;
464        }
465        false
466    }
467}
468
469/// flatten_errs flattens multiple errors into one
470pub fn flatten_errs(errs: Vec<impl Into<Error>>) -> Result<()> {
471    if errs.is_empty() {
472        Ok(())
473    } else {
474        let errs_strs: Vec<String> = errs.into_iter().map(|e| e.into().to_string()).collect();
475        Err(Error::new(errs_strs.join("\n")))
476    }
477}