Skip to main content

openmls/group/mls_group/
errors.rs

1//! # MlsGroup errors
2//!
3//! This module defines the public errors that can be returned from all calls
4//! to methods of [`MlsGroup`](super::MlsGroup).
5
6// These errors are exposed through `crate::group::errors`.
7
8use openmls_traits::types::Ciphersuite;
9use thiserror::Error;
10
11use crate::{
12    error::LibraryError,
13    extensions::errors::InvalidExtensionError,
14    group::{
15        errors::{
16            CreateAddProposalError, CreateCommitError, MergeCommitError, StageCommitError,
17            ValidationError,
18        },
19        CommitBuilderStageError, CreateGroupContextExtProposalError,
20    },
21    schedule::errors::PskError,
22    treesync::{
23        errors::{LeafNodeValidationError, PublicTreeError},
24        node::leaf_node::LeafNodeUpdateError,
25    },
26};
27
28#[cfg(feature = "extensions-draft")]
29pub use crate::schedule::application_export_tree::ApplicationExportTreeError;
30
31#[cfg(doc)]
32use crate::group::GroupId;
33
34/// New group error
35#[derive(Error, Debug, PartialEq, Clone)]
36pub enum NewGroupError<StorageError> {
37    /// See [`LibraryError`] for more details.
38    #[error(transparent)]
39    LibraryError(#[from] LibraryError),
40    /// No matching KeyPackage was found in the key store.
41    #[error("No matching KeyPackage was found in the key store.")]
42    NoMatchingKeyPackage,
43    /// Error accessing the storage.
44    #[error("Error accessing the storage.")]
45    StorageError(StorageError),
46    /// Unsupported proposal type in required capabilities.
47    #[error("Unsupported proposal type in required capabilities.")]
48    UnsupportedProposalType,
49    /// Unsupported extension type in required capabilities.
50    #[error("Unsupported extension type in required capabilities.")]
51    UnsupportedExtensionType,
52    /// Invalid extensions set in configuration
53    #[error("Invalid extensions set in configuration")]
54    InvalidExtensions(#[from] InvalidExtensionError),
55    /// A group with the given [`GroupId`] already exists.
56    #[error("A group with the given GroupId already exists.")]
57    GroupAlreadyExists,
58    /// The ciphersuite is not supported by the crypto provider.
59    #[error("Ciphersuite {0:?} is not supported by the crypto provider.")]
60    UnsupportedCiphersuite(Ciphersuite),
61    /// The leaf node's capabilities don't cover what the leaf itself uses.
62    #[error(transparent)]
63    LeafNodeBuild(#[from] crate::treesync::node::leaf_node::LeafNodeBuildError),
64    /// A virtual-clients processing error occurred.
65    #[cfg(feature = "virtual-clients-draft")]
66    #[error(transparent)]
67    VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
68    /// The group is an emulation group, and registering the derivation epoch of
69    /// its initial epoch failed.
70    #[cfg(feature = "virtual-clients-draft")]
71    #[error(transparent)]
72    RegisterVcDerivationEpoch(#[from] RegisterVcDerivationEpochError<StorageError>),
73}
74
75/// An error when deleting past epoch secrets.
76#[derive(Error, Debug, PartialEq, Eq, Clone)]
77pub enum DeletePastEpochSecretsError<StorageError> {
78    /// Error accessing the storage.
79    #[error(transparent)]
80    StorageError(#[from] StorageError),
81}
82
83/// An error when setting the past epoch deletion policy.
84#[derive(Error, Debug, PartialEq, Eq, Clone)]
85pub enum SetPastEpochDeletionPolicyError<StorageError> {
86    /// Error accessing the storage.
87    #[error(transparent)]
88    StorageError(#[from] StorageError),
89}
90
91/// EmptyInput error
92#[derive(Error, Debug, PartialEq, Eq, Clone)]
93pub enum EmptyInputError {
94    /// An empty list of KeyPackages was provided.
95    #[error("An empty list of KeyPackages was provided.")]
96    AddMembers,
97    /// An empty list of KeyPackage references was provided.
98    #[error("An empty list of KeyPackage references was provided.")]
99    RemoveMembers,
100}
101
102/// Group state error
103#[derive(Error, Debug, PartialEq, Clone)]
104pub enum MlsGroupStateError {
105    /// See [`LibraryError`] for more details.
106    #[error(transparent)]
107    LibraryError(#[from] LibraryError),
108    /// Tried to use a group after being evicted from it.
109    #[error("Tried to use a group after being evicted from it.")]
110    UseAfterEviction,
111    /// Can't create message because a pending proposal exists.
112    #[error("Can't create message because a pending proposal exists.")]
113    PendingProposal,
114    /// Can't execute operation because a pending commit exists.
115    #[error("Can't execute operation because a pending commit exists.")]
116    PendingCommit,
117    /// Can't execute operation because there is no pending commit.
118    #[error("Can't execute operation because there is no pending commit")]
119    NoPendingCommit,
120    /// Requested pending proposal hasn't been found in local pending proposals
121    #[error("Requested pending proposal hasn't been found in local pending proposals.")]
122    PendingProposalNotFound,
123}
124
125/// Error merging pending commit
126#[derive(Error, Debug, PartialEq, Clone)]
127pub enum MergePendingCommitError<StorageError> {
128    /// See [`MlsGroupStateError`] for more details.
129    #[error(transparent)]
130    MlsGroupStateError(#[from] MlsGroupStateError),
131    /// See [`MergeCommitError`] for more details.
132    #[error(transparent)]
133    MergeCommitError(#[from] MergeCommitError<StorageError>),
134}
135
136/// Process message error
137#[derive(Error, Debug, PartialEq, Clone)]
138pub enum PublicProcessMessageError {
139    /// See [`LibraryError`] for more details.
140    #[error(transparent)]
141    LibraryError(#[from] LibraryError),
142    /// The message's wire format is incompatible with the group's wire format policy.
143    #[error("The message's wire format is incompatible with the group's wire format policy.")]
144    IncompatibleWireFormat,
145    /// See [`ValidationError`] for more details.
146    #[error(transparent)]
147    ValidationError(#[from] ValidationError),
148    /// See [`StageCommitError`] for more details.
149    #[error(transparent)]
150    InvalidCommit(#[from] StageCommitError),
151    /// External application messages are not permitted.
152    #[error("External application messages are not permitted.")]
153    UnauthorizedExternalApplicationMessage,
154    /// External commit messages are not permitted.
155    #[error("Commit messages from external senders are not permitted.")]
156    UnauthorizedExternalCommitMessage,
157    /// The proposal is invalid for the Sender of type [External](crate::prelude::Sender::External)
158    #[error("The proposal is invalid for the Sender of type External")]
159    UnsupportedProposalType,
160
161    /// The group's GroupContext requires Safe AAD framing, but the message's
162    /// `authenticated_data` did not start with a well-formed `SafeAad`.
163    #[cfg(feature = "extensions-draft")]
164    #[error("malformed SafeAAD prefix in authenticated_data")]
165    MalformedSafeAad,
166}
167
168/// Process message error
169#[derive(Error, Debug, PartialEq, Clone)]
170pub enum ProcessMessageError<StorageError> {
171    /// See [`LibraryError`] for more details.
172    #[error(transparent)]
173    LibraryError(#[from] LibraryError),
174    /// Error writing to storage.
175    #[error("Error writing to storage: {0}")]
176    StorageError(StorageError),
177    /// The message's wire format is incompatible with the group's wire format policy.
178    #[error("The message's wire format is incompatible with the group's wire format policy.")]
179    IncompatibleWireFormat,
180    /// See [`ValidationError`] for more details.
181    #[error(transparent)]
182    ValidationError(#[from] ValidationError),
183    /// See [`MlsGroupStateError`] for more details.
184    #[error(transparent)]
185    GroupStateError(#[from] MlsGroupStateError),
186    /// See [`StageCommitError`] for more details.
187    #[error(transparent)]
188    InvalidCommit(#[from] StageCommitError),
189    /// External application messages are not permitted.
190    #[error("External application messages are not permitted.")]
191    UnauthorizedExternalApplicationMessage,
192    /// External commit messages are not permitted.
193    #[error("Commit messages from external senders are not permitted.")]
194    UnauthorizedExternalCommitMessage,
195    /// The proposal is invalid for the Sender of type [External](crate::prelude::Sender::External)
196    #[error("The proposal is invalid for the Sender of type External")]
197    UnsupportedProposalType,
198    /// The group's GroupContext requires Safe AAD framing, but the message's
199    /// `authenticated_data` did not start with a well-formed `SafeAad`.
200    #[cfg(feature = "extensions-draft")]
201    #[error("malformed SafeAAD prefix in authenticated_data")]
202    MalformedSafeAad,
203}
204
205/// Create message error
206#[cfg(not(feature = "virtual-clients-draft"))]
207#[derive(Error, Debug, PartialEq, Clone)]
208pub enum CreateMessageError {
209    /// See [`LibraryError`] for more details.
210    #[error(transparent)]
211    LibraryError(#[from] LibraryError),
212    /// See [`MlsGroupStateError`] for more details.
213    #[error(transparent)]
214    GroupStateError(#[from] MlsGroupStateError),
215}
216
217/// Add members error
218#[derive(Error, Debug, PartialEq, Clone)]
219pub enum AddMembersError<StorageError> {
220    /// See [`LibraryError`] for more details.
221    #[error(transparent)]
222    LibraryError(#[from] LibraryError),
223    /// See [`EmptyInputError`] for more details.
224    #[error(transparent)]
225    EmptyInput(#[from] EmptyInputError),
226    /// See [`CreateCommitError`] for more details.
227    #[error(transparent)]
228    CreateCommitError(#[from] CreateCommitError),
229    /// See [`CommitBuilderStageError`] for more details.
230    #[error(transparent)]
231    CommitBuilderStageError(#[from] CommitBuilderStageError<StorageError>),
232    /// See [`MlsGroupStateError`] for more details.
233    #[error(transparent)]
234    GroupStateError(#[from] MlsGroupStateError),
235    /// Error writing to storage.
236    #[error("Error writing to storage")]
237    StorageError(StorageError),
238}
239
240/// Add members error
241#[derive(Error, Debug, PartialEq, Clone)]
242pub enum SwapMembersError<StorageError> {
243    /// Unable to map the key packages to the given leaf indices.
244    #[error("Number of added and removed members is not the same")]
245    InvalidInput,
246
247    /// See [`EmptyInputError`] for more details.
248    #[error(transparent)]
249    EmptyInput(#[from] EmptyInputError),
250
251    /// See [`MlsGroupStateError`] for more details.
252    #[error(transparent)]
253    GroupStateError(#[from] MlsGroupStateError),
254
255    /// See [`LibraryError`] for more details.
256    #[error(transparent)]
257    LibraryError(#[from] LibraryError),
258
259    /// The member that should be removed can not be found.
260    #[error("The member that should be removed can not be found.")]
261    UnknownMember,
262
263    /// Error writing to storage
264    #[error("Error writing to storage: {0}")]
265    StorageError(StorageError),
266
267    /// See [`CommitBuilderStageError`] for more details.
268    #[error(transparent)]
269    CommitBuilderStageError(#[from] CommitBuilderStageError<StorageError>),
270
271    /// See [`CreateCommitError`] for more details.
272    #[error(transparent)]
273    CreateCommitError(#[from] CreateCommitError),
274}
275
276/// Propose add members error
277#[derive(Error, Debug, PartialEq, Clone)]
278pub enum ProposeAddMemberError<StorageError> {
279    /// See [`LibraryError`] for more details.
280    #[error(transparent)]
281    LibraryError(#[from] LibraryError),
282    /// The new member does not support all required extensions.
283    #[error("The new member does not support all required extensions.")]
284    UnsupportedExtensions,
285    /// See [`MlsGroupStateError`] for more details.
286    #[error(transparent)]
287    GroupStateError(#[from] MlsGroupStateError),
288    /// See [`LeafNodeValidationError`] for more details.
289    #[error(transparent)]
290    LeafNodeValidation(#[from] LeafNodeValidationError),
291    /// Error writing to storage
292    #[error("Error writing to storage: {0}")]
293    StorageError(StorageError),
294}
295
296/// Propose remove members error
297#[derive(Error, Debug, PartialEq, Clone)]
298pub enum ProposeRemoveMemberError<StorageError> {
299    /// See [`LibraryError`] for more details.
300    #[error(transparent)]
301    LibraryError(#[from] LibraryError),
302    /// See [`MlsGroupStateError`] for more details.
303    #[error(transparent)]
304    GroupStateError(#[from] MlsGroupStateError),
305    /// The member that should be removed can not be found.
306    #[error("The member that should be removed can not be found.")]
307    UnknownMember,
308    /// Error writing to storage
309    #[error("Error writing to storage: {0}")]
310    StorageError(StorageError),
311}
312
313/// Remove members error
314#[derive(Error, Debug, PartialEq, Clone)]
315pub enum RemoveMembersError<StorageError> {
316    /// See [`LibraryError`] for more details.
317    #[error(transparent)]
318    LibraryError(#[from] LibraryError),
319    /// See [`EmptyInputError`] for more details.
320    #[error(transparent)]
321    EmptyInput(#[from] EmptyInputError),
322    /// See [`CreateCommitError`] for more details.
323    #[error(transparent)]
324    CreateCommitError(#[from] CreateCommitError),
325    /// See [`CommitBuilderStageError`] for more details.
326    #[error(transparent)]
327    CommitBuilderStageError(#[from] CommitBuilderStageError<StorageError>),
328    /// See [`MlsGroupStateError`] for more details.
329    #[error(transparent)]
330    GroupStateError(#[from] MlsGroupStateError),
331    /// The member that should be removed can not be found.
332    #[error("The member that should be removed can not be found.")]
333    UnknownMember,
334    /// Error writing to storage
335    #[error("Error writing to storage: {0}")]
336    StorageError(StorageError),
337}
338
339/// Leave group error
340#[derive(Error, Debug, PartialEq, Clone)]
341pub enum LeaveGroupError<StorageError> {
342    /// See [`LibraryError`] for more details.
343    #[error(transparent)]
344    LibraryError(#[from] LibraryError),
345    /// See [`MlsGroupStateError`] for more details.
346    #[error(transparent)]
347    GroupStateError(#[from] MlsGroupStateError),
348    /// An error ocurred while writing to storage
349    #[error("An error ocurred while writing to storage")]
350    StorageError(StorageError),
351    /// SelfRemove not allowed with pure ciphertext outgoing wire format policy.
352    #[error("SelfRemove not allowed with pure ciphertext outgoing wire format policy.")]
353    CannotSelfRemoveWithPureCiphertext,
354}
355
356/// Self update error
357#[derive(Error, Debug, PartialEq, Clone)]
358pub enum SelfUpdateError<StorageError> {
359    /// See [`LibraryError`] for more details.
360    #[error(transparent)]
361    LibraryError(#[from] LibraryError),
362    /// See [`CreateCommitError`] for more details.
363    #[error(transparent)]
364    CreateCommitError(#[from] CreateCommitError),
365    /// See [`CommitBuilderStageError`] for more details.
366    #[error(transparent)]
367    CommitBuilderStageError(#[from] CommitBuilderStageError<StorageError>),
368    /// See [`MlsGroupStateError`] for more details.
369    #[error(transparent)]
370    GroupStateError(#[from] MlsGroupStateError),
371    /// Error accessing the storage.
372    #[error("Error accessing the storage.")]
373    StorageError(StorageError),
374    /// Virtual-clients error.
375    #[cfg(feature = "virtual-clients-draft")]
376    #[error(transparent)]
377    VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
378}
379
380/// Propose self update error
381#[derive(Error, Debug, PartialEq, Clone)]
382pub enum ProposeSelfUpdateError<StorageError> {
383    /// See [`LibraryError`] for more details.
384    #[error(transparent)]
385    LibraryError(#[from] LibraryError),
386
387    /// See [`MlsGroupStateError`] for more details.
388    #[error(transparent)]
389    GroupStateError(#[from] MlsGroupStateError),
390    /// Error accessing storage.
391    #[error("Error accessing storage.")]
392    StorageError(StorageError),
393    /// See [`PublicTreeError`] for more details.
394    #[error(transparent)]
395    PublicTreeError(#[from] PublicTreeError),
396    /// See [`LeafNodeUpdateError`] for more details.
397    #[error(transparent)]
398    LeafNodeUpdateError(#[from] LeafNodeUpdateError<StorageError>),
399    /// The updated leaf node does not support all group context extensions.
400    #[error("The updated leaf node does not support all group context extensions.")]
401    UnsupportedGroupContextExtensions,
402    /// The `leaf_node_parameters.credential_with_key` does not match
403    /// `new_signer.credential_with_key` (rotation paths only).
404    #[error("Mismatched credential_with_key between leaf_node_parameters and new_signer")]
405    InvalidLeafNodeParameters,
406    /// The `leaf_node_parameters.credential_with_key` does not match
407    /// `new_signer.credential_with_key` (rotation paths only).
408    #[error("Mismatched ciphersuite between new_signer and the group")]
409    InvalidSignerCiphersuite,
410}
411
412/// Commit to pending proposals error
413#[derive(Error, Debug, PartialEq, Clone)]
414pub enum CommitToPendingProposalsError<StorageError> {
415    /// See [`LibraryError`] for more details.
416    #[error(transparent)]
417    LibraryError(#[from] LibraryError),
418    /// See [`CreateCommitError`] for more details.
419    #[error(transparent)]
420    CreateCommitError(#[from] CreateCommitError),
421    /// See [`CommitBuilderStageError`] for more details.
422    #[error(transparent)]
423    CommitBuilderStageError(#[from] CommitBuilderStageError<StorageError>),
424    /// See [`MlsGroupStateError`] for more details.
425    #[error(transparent)]
426    GroupStateError(#[from] MlsGroupStateError),
427    /// Error writing to storage
428    #[error("Error writing to storage: {0}")]
429    StorageError(StorageError),
430}
431
432/// Errors that can happen when exporting a group info object.
433#[derive(Error, Debug, PartialEq, Clone)]
434pub enum ExportGroupInfoError {
435    /// See [`LibraryError`] for more details.
436    #[error(transparent)]
437    LibraryError(#[from] LibraryError),
438    /// See [`MlsGroupStateError`] for more details.
439    #[error(transparent)]
440    GroupStateError(#[from] MlsGroupStateError),
441    /// See [`InvalidExtensionError`] for more details.
442    #[error(transparent)]
443    InvalidExtensionError(#[from] InvalidExtensionError),
444}
445
446/// Export secret error
447#[cfg(feature = "extensions-draft")]
448#[derive(Error, Debug, PartialEq, Clone)]
449pub enum SafeExportSecretError<StorageError> {
450    /// See [`MlsGroupStateError`] for more details.
451    #[error(transparent)]
452    GroupState(#[from] MlsGroupStateError),
453    /// See [`ApplicationExportTreeError`] for more details.
454    #[error(transparent)]
455    ApplicationExportTree(#[from] ApplicationExportTreeError),
456    /// Group doesn't support application exports.
457    #[error("Group doesn't support application exports.")]
458    Unsupported,
459    /// Storage error
460    #[error("Error accessing storage: {0}")]
461    Storage(StorageError),
462}
463
464/// Error resolving a processed message carrying an unresolved app data commit.
465#[cfg(feature = "extensions-draft")]
466#[derive(Error, Debug, PartialEq, Clone)]
467pub enum ResolveAppDataCommitError {
468    /// The processed message does not carry an unresolved app data commit.
469    #[error("The processed message does not carry an unresolved app data commit.")]
470    NotAnUnresolvedAppDataCommit,
471    /// See [`StageCommitError`] for more details.
472    #[error(transparent)]
473    StageCommit(#[from] StageCommitError),
474}
475
476/// Export secret error
477#[cfg(feature = "extensions-draft")]
478#[derive(Error, Debug, PartialEq, Clone)]
479pub enum ProcessedMessageSafeExportSecretError {
480    /// See [`StagedSafeExportSecretError`] for more details.
481    #[error(transparent)]
482    SafeExportSecretError(#[from] StagedSafeExportSecretError),
483    /// Processed message is not a commit.
484    #[error("Processed message is not a commit.")]
485    NotACommit,
486}
487
488/// Export secret error
489#[cfg(feature = "extensions-draft")]
490#[derive(Error, Debug, PartialEq, Clone)]
491pub enum PendingSafeExportSecretError<StorageError> {
492    /// See [`StagedSafeExportSecretError`] for more details.
493    #[error(transparent)]
494    SafeExportSecretError(#[from] StagedSafeExportSecretError),
495    /// No pending commit.
496    #[error("No pending commit.")]
497    NoPendingCommit,
498    /// Storage error
499    #[error("Error accessing storage: {0}")]
500    Storage(StorageError),
501    /// Only group members can export secrets.
502    #[error("Only group members can export secrets.")]
503    NotGroupMember,
504}
505
506/// Export secret from a pending commit
507#[cfg(feature = "extensions-draft")]
508#[derive(Error, Debug, PartialEq, Clone)]
509pub enum StagedSafeExportSecretError {
510    /// Only group members can export secrets.
511    #[error("Only group members can export secrets.")]
512    NotGroupMember,
513    /// See [`ApplicationExportTreeError`] for more details.
514    #[error(transparent)]
515    ApplicationExportTree(#[from] ApplicationExportTreeError),
516    /// Group doesn't support application exports.
517    #[error("Group doesn't support application exports.")]
518    Unsupported,
519}
520
521/// Export secret error
522#[derive(Error, Debug, PartialEq, Clone)]
523pub enum ExportSecretError {
524    /// See [`LibraryError`] for more details.
525    #[error(transparent)]
526    LibraryError(#[from] LibraryError),
527    /// The requested key length is too long.
528    #[error("The requested key length is too long.")]
529    KeyLengthTooLong,
530    /// See [`MlsGroupStateError`] for more details.
531    #[error(transparent)]
532    GroupStateError(#[from] MlsGroupStateError),
533}
534
535/// Propose PSK error
536#[derive(Error, Debug, PartialEq, Clone)]
537pub enum ProposePskError {
538    /// See [`PskError`] for more details.
539    #[error(transparent)]
540    Psk(#[from] PskError),
541    /// See [`MlsGroupStateError`] for more details.
542    #[error(transparent)]
543    GroupStateError(#[from] MlsGroupStateError),
544    /// See [`LibraryError`] for more details.
545    #[error(transparent)]
546    LibraryError(#[from] LibraryError),
547}
548
549/// Proposal error
550#[derive(Error, Debug, PartialEq, Clone)]
551pub enum ProposalError<StorageError> {
552    /// See [`LibraryError`] for more details.
553    #[error(transparent)]
554    LibraryError(#[from] LibraryError),
555    /// See [`ProposeAddMemberError`] for more details.
556    #[error(transparent)]
557    ProposeAddMemberError(#[from] ProposeAddMemberError<StorageError>),
558    /// See [`CreateAddProposalError`] for more details.
559    #[error(transparent)]
560    CreateAddProposalError(#[from] CreateAddProposalError),
561    /// See [`ProposeSelfUpdateError`] for more details.
562    #[error(transparent)]
563    ProposeSelfUpdateError(#[from] ProposeSelfUpdateError<StorageError>),
564    /// See [`ProposeRemoveMemberError`] for more details.
565    #[error(transparent)]
566    ProposeRemoveMemberError(#[from] ProposeRemoveMemberError<StorageError>),
567    /// See [`MlsGroupStateError`] for more details.
568    #[error(transparent)]
569    GroupStateError(#[from] MlsGroupStateError),
570    /// See [`ValidationError`] for more details.
571    #[error(transparent)]
572    ValidationError(#[from] ValidationError),
573    /// See [`CreateGroupContextExtProposalError`] for more details.
574    #[error(transparent)]
575    CreateGroupContextExtProposalError(#[from] CreateGroupContextExtProposalError<StorageError>),
576    /// See [`InvalidExtensionError`]
577    #[error(transparent)]
578    InvalidExtension(#[from] InvalidExtensionError),
579    /// Error writing proposal to storage.
580    #[error("error writing proposal to storage")]
581    StorageError(StorageError),
582}
583
584/// Remove proposal error
585#[derive(Error, Debug, PartialEq, Clone)]
586pub enum RemoveProposalError<StorageError> {
587    /// Couldn't find the proposal for the given `ProposalRef`.
588    #[error("Couldn't find the proposal for the given `ProposalRef`")]
589    ProposalNotFound,
590    /// Error erasing proposal from storage.
591    #[error("error writing proposal to storage")]
592    Storage(StorageError),
593}
594
595#[cfg(feature = "virtual-clients-draft")]
596pub use virtual_clients_draft::*;
597
598#[cfg(feature = "virtual-clients-draft")]
599mod virtual_clients_draft {
600    use thiserror::Error;
601
602    use super::MlsGroupStateError;
603    use crate::error::LibraryError;
604    use crate::framing::MessageEncryptionError;
605    use crate::tree::secret_tree::SecretTreeError;
606
607    /// Create message error
608    #[derive(Error, Debug, PartialEq, Clone)]
609    pub enum CreateMessageError<StorageError> {
610        /// See [`LibraryError`] for more details.
611        #[error(transparent)]
612        LibraryError(#[from] LibraryError),
613        /// See [`MlsGroupStateError`] for more details.
614        #[error(transparent)]
615        GroupStateError(#[from] MlsGroupStateError),
616        /// See [`MessageEncryptionError`] for more details.
617        #[error(transparent)]
618        MessageEncryptionError(#[from] MessageEncryptionError<StorageError>),
619        /// Error writing to storage.
620        #[error("Error writing to storage: {0}")]
621        StorageError(StorageError),
622    }
623
624    /// Confirm message error
625    #[derive(Error, Debug, PartialEq, Clone)]
626    pub enum ConfirmMessageError<StorageError> {
627        /// See [`SecretTreeError`] for more details.
628        #[error(transparent)]
629        SecretTreeError(#[from] SecretTreeError),
630        /// The requested epoch is newer than the group's current epoch.
631        #[error("The requested epoch is newer than the group's current epoch.")]
632        FutureEpoch,
633        /// Error writing to storage.
634        #[error("Error writing to storage: {0}")]
635        StorageError(StorageError),
636    }
637
638    impl<StorageError> From<ConfirmMessageError<StorageError>> for CreateMessageError<StorageError> {
639        fn from(err: ConfirmMessageError<StorageError>) -> Self {
640            match err {
641                ConfirmMessageError::SecretTreeError(e) => {
642                    CreateMessageError::MessageEncryptionError(
643                        MessageEncryptionError::SecretTreeError(e),
644                    )
645                }
646                // Unreachable: `create_message` confirms at the current epoch,
647                // which never triggers the future-epoch guard.
648                ConfirmMessageError::FutureEpoch => CreateMessageError::LibraryError(
649                    LibraryError::custom("confirm_application_message reported a future epoch"),
650                ),
651                ConfirmMessageError::StorageError(e) => CreateMessageError::StorageError(e),
652            }
653        }
654    }
655
656    /// Errors returned when deriving and persisting the state of a
657    /// virtual-clients derivation epoch. OpenMLS does this implicitly for
658    /// emulation groups, so this error is always wrapped in the error of the
659    /// operation that triggered the registration.
660    ///
661    /// See [`MlsGroupCreateConfigBuilder::emulation_group`](crate::group::MlsGroupCreateConfigBuilder::emulation_group).
662    #[derive(Error, Debug, PartialEq, Clone)]
663    pub enum RegisterVcDerivationEpochError<StorageError> {
664        /// Puncturing the application exporter for the virtual-clients
665        /// component failed. See
666        /// [`ApplicationExportTreeError`](super::ApplicationExportTreeError) for
667        /// more details.
668        #[error(transparent)]
669        ApplicationExportTree(#[from] super::ApplicationExportTreeError),
670        /// The emulation group has no application export tree to source the
671        /// derivation epoch from. This happens when a group stored by an
672        /// OpenMLS version without application-exporter support is marked as
673        /// an emulation group.
674        #[error(
675            "The emulation group has no application export tree to source the derivation epoch \
676             from."
677        )]
678        MissingApplicationExportTree,
679        /// See [`VirtualClientsError`](crate::components::vc_derivation_info::VirtualClientsError)
680        /// for more details.
681        #[error(transparent)]
682        VirtualClients(#[from] crate::components::vc_derivation_info::VirtualClientsError),
683        /// Persisting the derived virtual-clients state to storage failed.
684        #[error("Error writing virtual-clients state to storage")]
685        Storage(StorageError),
686    }
687}