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