1use ::routing::error::{ComponentInstanceError, RoutingError};
6use ::routing::policy::PolicyError;
7use ::routing::resolving::ResolverError;
8use anyhow::Error;
9use clonable_error::ClonableError;
10use cm_config::CompatibilityCheckError;
11use cm_rust::UseDecl;
12use cm_types::{Name, Url};
13use component_id_index::InstanceId;
14use fuchsia_fs::directory::WatcherCreateError;
15use moniker::{ChildName, ExtendedMoniker, Moniker, MonikerError};
16use router_error::{Explain, RouterError};
17use sandbox::ConversionError;
18use serve_processargs::BuildNamespaceError;
19use std::sync::Arc;
20use thiserror::Error;
21use {fidl_fuchsia_component as fcomponent, fidl_fuchsia_sys2 as fsys};
22
23#[derive(Debug, Error, Clone)]
25pub enum ModelError {
26 #[error("bad path")]
27 BadPath,
28 #[error(transparent)]
29 MonikerError {
30 #[from]
31 err: MonikerError,
32 },
33 #[error("expected a component instance moniker")]
34 UnexpectedComponentManagerMoniker,
35 #[error(transparent)]
36 RoutingError {
37 #[from]
38 err: RoutingError,
39 },
40 #[error(
41 "opening path `{path}`, in storage directory for `{moniker}` backed by `{source_moniker}`: {err}"
42 )]
43 OpenStorageFailed {
44 source_moniker: ExtendedMoniker,
45 moniker: Moniker,
46 path: String,
47 #[source]
48 err: zx::Status,
49 },
50 #[error(transparent)]
51 StorageError {
52 #[from]
53 err: StorageError,
54 },
55 #[error(transparent)]
56 ComponentInstanceError {
57 #[from]
58 err: ComponentInstanceError,
59 },
60 #[error("service dir VFS for component {moniker}:\n\t{err}")]
61 ServiceDirError {
62 moniker: Moniker,
63
64 #[source]
65 err: VfsError,
66 },
67 #[error("opening directory `{relative_path}` for component `{moniker}` failed")]
68 OpenDirectoryError { moniker: Moniker, relative_path: String },
69 #[error("events: {err}")]
70 EventsError {
71 #[from]
72 err: EventsError,
73 },
74 #[error(transparent)]
75 PolicyError {
76 #[from]
77 err: PolicyError,
78 },
79 #[error("component id index: {err}")]
80 ComponentIdIndexError {
81 #[from]
82 err: component_id_index::IndexError,
83 },
84 #[error(transparent)]
85 ActionError {
86 #[from]
87 err: ActionError,
88 },
89 #[error("resolve: {err}")]
90 ResolveActionError {
91 #[from]
92 err: ResolveActionError,
93 },
94 #[error("start: {err}")]
95 StartActionError {
96 #[from]
97 err: StartActionError,
98 },
99 #[error("open outgoing dir: {err}")]
100 OpenOutgoingDirError {
101 #[from]
102 err: OpenOutgoingDirError,
103 },
104 #[error("router: {err}")]
105 RouterError {
106 #[from]
107 err: RouterError,
108 },
109 #[error("capability provider: {err}")]
110 CapabilityProviderError {
111 #[from]
112 err: CapabilityProviderError,
113 },
114 #[error("open: {err}")]
115 OpenError {
116 #[from]
117 err: OpenError,
118 },
119}
120
121impl ModelError {
122 pub fn instance_not_found(moniker: Moniker) -> ModelError {
123 ModelError::from(ComponentInstanceError::instance_not_found(moniker))
124 }
125
126 pub fn open_directory_error(moniker: Moniker, relative_path: impl Into<String>) -> ModelError {
127 ModelError::OpenDirectoryError { moniker, relative_path: relative_path.into() }
128 }
129}
130
131impl ModelError {
132 fn as_zx_status(&self) -> zx::Status {
133 match self {
134 ModelError::RoutingError { err } => err.as_zx_status(),
135 ModelError::PolicyError { err } => err.as_zx_status(),
136 ModelError::StartActionError { err } => err.as_zx_status(),
137 ModelError::ComponentInstanceError { err } => err.as_zx_status(),
138 ModelError::OpenOutgoingDirError { err } => err.as_zx_status(),
139 ModelError::RouterError { err } => err.as_zx_status(),
140 ModelError::CapabilityProviderError { err } => err.as_zx_status(),
141 _ => zx::Status::INTERNAL,
143 }
144 }
145}
146
147#[derive(Debug, Error, Clone)]
148pub enum StructuredConfigError {
149 #[error("component has a config schema but resolver did not provide values")]
150 ConfigValuesMissing,
151 #[error("failed to resolve component's config:\n\t{_0}")]
152 ConfigResolutionFailed(#[source] config_encoder::ResolutionError),
153 #[error("couldn't create vmo: {_0}")]
154 VmoCreateFailed(#[source] zx::Status),
155 #[error("failed to match values for key `{key}`")]
156 ValueMismatch { key: String },
157 #[error("failed to find values for key `{key}`")]
158 KeyNotFound { key: String },
159 #[error("failed to route structured config values:\n\t{_0}")]
160 RoutingError(#[from] router_error::RouterError),
161}
162
163#[derive(Clone, Debug, Error)]
164pub enum VfsError {
165 #[error("failed to add node `{name}`: {status}")]
166 AddNodeError { name: String, status: zx::Status },
167 #[error("failed to remove node `{name}`: {status}")]
168 RemoveNodeError { name: String, status: zx::Status },
169}
170
171#[derive(Debug, Error)]
172pub enum RebootError {
173 #[error("failed to connect to admin protocol in root component's exposed dir:\n\t{0}")]
174 ConnectToAdminFailed(#[source] anyhow::Error),
175 #[error("StateControl Admin FIDL:\n\t{0}")]
176 FidlError(#[from] fidl::Error),
177 #[error("StateControl Admin: {0}")]
178 AdminError(zx::Status),
179 #[error("opening root component's exposed dir: {0}")]
180 OpenRootExposedDirFailed(#[from] OpenExposedDirError),
181}
182
183#[derive(Debug, Error)]
184pub enum OpenExposedDirError {
185 #[error("instance is not resolved")]
186 InstanceNotResolved,
187 #[error("instance was destroyed")]
188 InstanceDestroyed,
189 #[error("open error: {0}")]
190 Open(#[from] zx::Status),
191}
192
193impl Explain for OpenExposedDirError {
194 fn as_zx_status(&self) -> zx::Status {
195 match self {
196 Self::InstanceNotResolved => zx::Status::NOT_FOUND,
197 Self::InstanceDestroyed => zx::Status::NOT_FOUND,
198 Self::Open(status) => *status,
199 }
200 }
201}
202
203impl From<OpenExposedDirError> for fsys::OpenError {
204 fn from(value: OpenExposedDirError) -> Self {
205 match value {
206 OpenExposedDirError::InstanceNotResolved => fsys::OpenError::InstanceNotResolved,
207 OpenExposedDirError::InstanceDestroyed => fsys::OpenError::InstanceDestroyed,
208 OpenExposedDirError::Open(_) => fsys::OpenError::FidlError,
209 }
210 }
211}
212
213#[derive(Clone, Debug, Error)]
214pub enum OpenOutgoingDirError {
215 #[error("instance is not resolved")]
216 InstanceNotResolved,
217 #[error("instance is non-executable")]
218 InstanceNonExecutable,
219 #[error("failed to open: {0}")]
220 Open(#[from] zx::Status),
221 #[error("fidl IPC to protocol in outgoing directory:\n\t{0}")]
222 Fidl(fidl::Error),
223}
224
225impl Explain for OpenOutgoingDirError {
226 fn as_zx_status(&self) -> zx::Status {
227 match self {
228 Self::InstanceNotResolved => zx::Status::NOT_FOUND,
229 Self::InstanceNonExecutable => zx::Status::NOT_FOUND,
230 Self::Open(err) => *err,
231 Self::Fidl(_) => zx::Status::NOT_FOUND,
232 }
233 }
234}
235
236impl From<OpenOutgoingDirError> for fsys::OpenError {
237 fn from(value: OpenOutgoingDirError) -> Self {
238 match value {
239 OpenOutgoingDirError::InstanceNotResolved => fsys::OpenError::InstanceNotResolved,
240 OpenOutgoingDirError::InstanceNonExecutable => fsys::OpenError::NoSuchDir,
241 OpenOutgoingDirError::Open(_) => fsys::OpenError::FidlError,
242 OpenOutgoingDirError::Fidl(_) => fsys::OpenError::FidlError,
243 }
244 }
245}
246
247impl From<OpenOutgoingDirError> for RouterError {
248 fn from(value: OpenOutgoingDirError) -> Self {
249 Self::NotFound(Arc::new(value))
250 }
251}
252
253#[derive(Debug, Error, Clone)]
254pub enum AddDynamicChildError {
255 #[error("component collection not found with name `{name}`")]
256 CollectionNotFound { name: String },
257 #[error(
258 "numbered handles can only be provided when adding components to a single-run collection"
259 )]
260 NumberedHandleNotInSingleRunCollection,
261 #[error("name length is longer than the allowed max of {max_len}")]
262 NameTooLong { max_len: usize },
263 #[error("collection `{collection_name}` does not allow dynamic offers")]
264 DynamicOffersNotAllowed { collection_name: String },
265 #[error(transparent)]
266 ActionError {
267 #[from]
268 err: ActionError,
269 },
270 #[error("invalid dictionary")]
271 InvalidDictionary,
272 #[error(
273 "dictionary entry for capability `{capability_name}` conflicts with existing static route"
274 )]
275 StaticRouteConflict { capability_name: Name },
276 #[error(transparent)]
277 AddChildError {
278 #[from]
279 err: AddChildError,
280 },
281 #[error("cannot set both `dictionary` and `additional_inputs`")]
282 DictionaryAndAdditionalInputsSet,
283}
284
285impl Into<fcomponent::Error> for AddDynamicChildError {
287 fn into(self) -> fcomponent::Error {
288 match self {
289 AddDynamicChildError::CollectionNotFound { .. } => {
290 fcomponent::Error::CollectionNotFound
291 }
292 AddDynamicChildError::NumberedHandleNotInSingleRunCollection => {
293 fcomponent::Error::Unsupported
294 }
295 AddDynamicChildError::AddChildError {
296 err: AddChildError::InstanceAlreadyExists { .. },
297 } => fcomponent::Error::InstanceAlreadyExists,
298 AddDynamicChildError::DynamicOffersNotAllowed { .. } => {
299 fcomponent::Error::InvalidArguments
300 }
301 AddDynamicChildError::ActionError { err } => err.into(),
302 AddDynamicChildError::InvalidDictionary { .. } => fcomponent::Error::InvalidArguments,
303 AddDynamicChildError::StaticRouteConflict { .. } => fcomponent::Error::InvalidArguments,
304 AddDynamicChildError::NameTooLong { .. } => fcomponent::Error::InvalidArguments,
305 AddDynamicChildError::AddChildError {
308 err:
309 AddChildError::DynamicCapabilityError { err: DynamicCapabilityError::Cycle { .. } },
310 } => fcomponent::Error::DependencyCycle,
311 AddDynamicChildError::AddChildError {
312 err: AddChildError::DynamicCapabilityError { .. },
313 } => fcomponent::Error::InvalidArguments,
314 AddDynamicChildError::AddChildError { err: AddChildError::ChildNameInvalid { .. } } => {
315 fcomponent::Error::InvalidArguments
316 }
317 AddDynamicChildError::DictionaryAndAdditionalInputsSet => {
318 fcomponent::Error::InvalidArguments
319 }
320 }
321 }
322}
323
324impl Into<fsys::CreateError> for AddDynamicChildError {
326 fn into(self) -> fsys::CreateError {
327 match self {
328 AddDynamicChildError::CollectionNotFound { .. } => {
329 fsys::CreateError::CollectionNotFound
330 }
331 AddDynamicChildError::AddChildError {
332 err: AddChildError::InstanceAlreadyExists { .. },
333 } => fsys::CreateError::InstanceAlreadyExists,
334
335 AddDynamicChildError::DynamicOffersNotAllowed { .. } => {
336 fsys::CreateError::DynamicOffersForbidden
337 }
338 AddDynamicChildError::ActionError { .. } => fsys::CreateError::Internal,
339 AddDynamicChildError::InvalidDictionary { .. } => fsys::CreateError::Internal,
340 AddDynamicChildError::StaticRouteConflict { .. } => fsys::CreateError::Internal,
341 AddDynamicChildError::NameTooLong { .. } => fsys::CreateError::BadChildDecl,
342 AddDynamicChildError::AddChildError {
343 err: AddChildError::DynamicCapabilityError { .. },
344 } => fsys::CreateError::BadDynamicOffer,
345 AddDynamicChildError::AddChildError { err: AddChildError::ChildNameInvalid { .. } } => {
346 fsys::CreateError::BadMoniker
347 }
348 AddDynamicChildError::NumberedHandleNotInSingleRunCollection => {
349 fsys::CreateError::NumberedHandlesForbidden
350 }
351 AddDynamicChildError::DictionaryAndAdditionalInputsSet => {
352 fsys::CreateError::DictionaryAndAdditionalInputsSet
353 }
354 }
355 }
356}
357
358#[derive(Debug, Error, Clone)]
359pub enum AddChildError {
360 #[error("component instance `{child}` in realm `{moniker}` already exists")]
361 InstanceAlreadyExists { moniker: Moniker, child: ChildName },
362 #[error(transparent)]
363 DynamicCapabilityError {
364 #[from]
365 err: DynamicCapabilityError,
366 },
367 #[error("invalid child name: {err}")]
368 ChildNameInvalid {
369 #[from]
370 err: MonikerError,
371 },
372}
373
374#[derive(Debug, Error, Clone, PartialEq)]
375pub enum DynamicCapabilityError {
376 #[error("a dynamic capability was not valid:\n\t{err}")]
377 Invalid {
378 #[source]
379 err: cm_fidl_validator::error::ErrorList,
380 },
381 #[error("dynamic offers are not allowed for {typename}")]
382 UnsupportedType { typename: &'static str },
383 #[error("dynamic offer would create a cycle:\n\t{err}")]
384 Cycle {
385 #[source]
386 err: cm_fidl_validator::error::ErrorList,
387 },
388 #[error("source for dynamic offer not found:\n\t{:?}", offer)]
389 SourceNotFound { offer: cm_rust::OfferDecl },
390 #[error("unknown offer type in dynamic offers")]
391 UnknownOfferType,
392}
393
394#[derive(Debug, Clone, Error)]
395#[error(transparent)]
396pub struct ActionError {
397 kind: Box<ActionErrorKind>,
398}
399
400impl ActionError {
401 pub fn kind(&self) -> &ActionErrorKind {
402 &self.kind
403 }
404}
405
406impl From<ActionErrorKind> for ActionError {
407 fn from(err: ActionErrorKind) -> Self {
408 ActionError { kind: Box::new(err) }
409 }
410}
411
412macro_rules! impl_from_action_error_kind {
413 ($($ty:ty,)+) => {
414 $(
415 impl From<$ty> for ActionError {
416 fn from(err: $ty) -> Self {
417 ActionError::from(ActionErrorKind::from(err))
418 }
419 }
420 )+
421 }
422}
423
424impl_from_action_error_kind! {
425 DiscoverActionError,
426 ResolveActionError,
427 UnresolveActionError,
428 StartActionError,
429 StopActionError,
430 DestroyActionError,
431 ShutdownActionError,
432}
433
434#[derive(Debug, Clone, Error)]
435pub enum ActionErrorKind {
436 #[error("discover: {err}")]
437 DiscoverError {
438 #[from]
439 err: DiscoverActionError,
440 },
441
442 #[error("resolve: {err}")]
443 ResolveError {
444 #[from]
445 err: ResolveActionError,
446 },
447
448 #[error("unresolve: {err}")]
449 UnresolveError {
450 #[from]
451 err: UnresolveActionError,
452 },
453
454 #[error("start: {err}")]
455 StartError {
456 #[from]
457 err: StartActionError,
458 },
459
460 #[error("stop: {err}")]
461 StopError {
462 #[from]
463 err: StopActionError,
464 },
465
466 #[error("destroy: {err}")]
467 DestroyError {
468 #[from]
469 err: DestroyActionError,
470 },
471
472 #[error("shutdown: {err}")]
473 ShutdownError {
474 #[from]
475 err: ShutdownActionError,
476 },
477}
478
479impl Explain for ActionError {
480 fn as_zx_status(&self) -> zx::Status {
481 match &*self.kind {
482 ActionErrorKind::DiscoverError { .. } => zx::Status::INTERNAL,
483 ActionErrorKind::ResolveError { err } => err.as_zx_status(),
484 ActionErrorKind::UnresolveError { .. } => zx::Status::INTERNAL,
485 ActionErrorKind::StartError { err } => err.as_zx_status(),
486 ActionErrorKind::StopError { .. } => zx::Status::INTERNAL,
487 ActionErrorKind::DestroyError { .. } => zx::Status::INTERNAL,
488 ActionErrorKind::ShutdownError { .. } => zx::Status::INTERNAL,
489 }
490 }
491}
492
493impl From<ActionError> for fcomponent::Error {
494 fn from(err: ActionError) -> Self {
495 match *err.kind {
496 ActionErrorKind::DiscoverError { .. } => fcomponent::Error::Internal,
497 ActionErrorKind::ResolveError { .. } => fcomponent::Error::Internal,
498 ActionErrorKind::UnresolveError { .. } => fcomponent::Error::Internal,
499 ActionErrorKind::StartError { err } => err.into(),
500 ActionErrorKind::StopError { err } => err.into(),
501 ActionErrorKind::DestroyError { err } => err.into(),
502 ActionErrorKind::ShutdownError { .. } => fcomponent::Error::Internal,
503 }
504 }
505}
506
507impl From<ActionError> for fsys::ResolveError {
508 fn from(err: ActionError) -> Self {
509 match *err.kind {
510 ActionErrorKind::ResolveError { err } => err.into(),
511 _ => fsys::ResolveError::Internal,
512 }
513 }
514}
515
516impl From<ActionError> for fsys::UnresolveError {
517 fn from(err: ActionError) -> Self {
518 match *err.kind {
519 ActionErrorKind::UnresolveError { err } => err.into(),
520 _ => fsys::UnresolveError::Internal,
521 }
522 }
523}
524
525impl From<ActionError> for fsys::StartError {
526 fn from(err: ActionError) -> Self {
527 match *err.kind {
528 ActionErrorKind::StartError { err } => err.into(),
529 _ => fsys::StartError::Internal,
530 }
531 }
532}
533
534impl From<ActionError> for fsys::StopError {
535 fn from(err: ActionError) -> Self {
536 match *err.kind {
537 ActionErrorKind::StopError { err } => err.into(),
538 _ => fsys::StopError::Internal,
539 }
540 }
541}
542
543impl From<ActionError> for fsys::DestroyError {
544 fn from(err: ActionError) -> Self {
545 match *err.kind {
546 ActionErrorKind::DestroyError { err } => err.into(),
547 _ => fsys::DestroyError::Internal,
548 }
549 }
550}
551
552#[derive(Debug, Clone, Error)]
553pub enum DiscoverActionError {
554 #[error("`{moniker}` was destroyed")]
555 InstanceDestroyed { moniker: Moniker },
556}
557
558#[derive(Debug, Clone, Error)]
559pub enum ResolveActionError {
560 #[error("discover during resolve: {err}")]
561 DiscoverActionError {
562 #[from]
563 err: DiscoverActionError,
564 },
565 #[error("`{moniker}` was shut down")]
566 InstanceShutDown { moniker: Moniker },
567 #[error("`{moniker}` was destroyed")]
568 InstanceDestroyed { moniker: Moniker },
569 #[error("could not parse component address for `{url}` at `{moniker}`:\n\t{err}")]
570 ComponentAddressParseError {
571 url: Url,
572 moniker: Moniker,
573 #[source]
574 err: ResolverError,
575 },
576 #[error("resolve failed for `{url}`:\n\t{err}")]
577 ResolverError {
578 url: Url,
579 #[source]
580 err: ResolverError,
581 },
582 #[error("expose dir for `{moniker}`:\n\t{err}")]
583 ExposeDirError {
585 moniker: Moniker,
586
587 #[source]
588 err: VfsError,
589 },
590 #[error("adding static child `{child_name}`:\n\t{err}")]
591 AddStaticChildError {
592 child_name: String,
593 #[source]
594 err: AddChildError,
595 },
596 #[error("structured config: {err}")]
597 StructuredConfigError {
598 #[from]
599 err: StructuredConfigError,
600 },
601 #[error("creating package dir proxy: {err}")]
602 PackageDirProxyCreateError {
603 #[source]
604 err: fidl::Error,
605 },
606 #[error("ABI compatibility check for `{url}`: {err}")]
607 AbiCompatibilityError {
608 url: Url,
609 #[source]
610 err: CompatibilityCheckError,
611 },
612 #[error(transparent)]
613 Policy(#[from] PolicyError),
614 #[error("`{moniker}` was interrupted")]
615 Aborted { moniker: Moniker },
616}
617
618impl ResolveActionError {
619 fn as_zx_status(&self) -> zx::Status {
620 match self {
621 ResolveActionError::DiscoverActionError { .. }
622 | ResolveActionError::InstanceShutDown { .. }
623 | ResolveActionError::InstanceDestroyed { .. }
624 | ResolveActionError::ComponentAddressParseError { .. }
625 | ResolveActionError::AbiCompatibilityError { .. } => zx::Status::NOT_FOUND,
626 ResolveActionError::ExposeDirError { .. }
627 | ResolveActionError::AddStaticChildError { .. }
628 | ResolveActionError::StructuredConfigError { .. }
629 | ResolveActionError::Aborted { .. }
630 | ResolveActionError::PackageDirProxyCreateError { .. } => zx::Status::INTERNAL,
631 ResolveActionError::ResolverError { err, .. } => err.as_zx_status(),
632 ResolveActionError::Policy(err) => err.as_zx_status(),
633 }
634 }
635}
636
637impl Into<fsys::ResolveError> for ResolveActionError {
639 fn into(self) -> fsys::ResolveError {
640 match self {
641 ResolveActionError::ResolverError {
642 err: ResolverError::PackageNotFound(_), ..
643 } => fsys::ResolveError::PackageNotFound,
644 ResolveActionError::ResolverError {
645 err: ResolverError::ManifestNotFound(_), ..
646 } => fsys::ResolveError::ManifestNotFound,
647 ResolveActionError::InstanceShutDown { .. }
648 | ResolveActionError::InstanceDestroyed { .. } => fsys::ResolveError::InstanceNotFound,
649 ResolveActionError::ExposeDirError { .. }
650 | ResolveActionError::ResolverError { .. }
651 | ResolveActionError::StructuredConfigError { .. }
652 | ResolveActionError::ComponentAddressParseError { .. }
653 | ResolveActionError::AddStaticChildError { .. }
654 | ResolveActionError::DiscoverActionError { .. }
655 | ResolveActionError::AbiCompatibilityError { .. }
656 | ResolveActionError::Aborted { .. }
657 | ResolveActionError::PackageDirProxyCreateError { .. } => fsys::ResolveError::Internal,
658 ResolveActionError::Policy(_) => fsys::ResolveError::PolicyError,
659 }
660 }
661}
662
663impl Into<fsys::StartError> for ResolveActionError {
666 fn into(self) -> fsys::StartError {
667 match self {
668 ResolveActionError::ResolverError {
669 err: ResolverError::PackageNotFound(_), ..
670 } => fsys::StartError::PackageNotFound,
671 ResolveActionError::ResolverError {
672 err: ResolverError::ManifestNotFound(_), ..
673 } => fsys::StartError::ManifestNotFound,
674 ResolveActionError::InstanceShutDown { .. }
675 | ResolveActionError::InstanceDestroyed { .. } => fsys::StartError::InstanceNotFound,
676 ResolveActionError::ExposeDirError { .. }
677 | ResolveActionError::ResolverError { .. }
678 | ResolveActionError::StructuredConfigError { .. }
679 | ResolveActionError::ComponentAddressParseError { .. }
680 | ResolveActionError::AddStaticChildError { .. }
681 | ResolveActionError::DiscoverActionError { .. }
682 | ResolveActionError::AbiCompatibilityError { .. }
683 | ResolveActionError::Aborted { .. }
684 | ResolveActionError::PackageDirProxyCreateError { .. } => fsys::StartError::Internal,
685 ResolveActionError::Policy(_) => fsys::StartError::PolicyError,
686 }
687 }
688}
689
690#[derive(Debug, Clone, Error)]
691pub enum PkgDirError {
692 #[error("no pkg dir found for component")]
693 NoPkgDir,
694 #[error("opening pkg dir failed: {err}")]
695 OpenFailed {
696 #[from]
697 err: zx::Status,
698 },
699}
700
701impl PkgDirError {
702 fn as_zx_status(&self) -> zx::Status {
703 match self {
704 Self::NoPkgDir => zx::Status::NOT_FOUND,
705 Self::OpenFailed { err } => *err,
706 }
707 }
708}
709
710#[derive(Debug, Clone, Error)]
711pub enum ComponentProviderError {
712 #[error("starting source instance:\n\t{err}")]
713 SourceStartError {
714 #[from]
715 err: ActionError,
716 },
717 #[error("opening source instance's outgoing dir:\n\t{err}")]
718 OpenOutgoingDirError {
719 #[from]
720 err: OpenOutgoingDirError,
721 },
722}
723
724impl ComponentProviderError {
725 pub fn as_zx_status(&self) -> zx::Status {
726 match self {
727 Self::SourceStartError { err } => err.as_zx_status(),
728 Self::OpenOutgoingDirError { err } => err.as_zx_status(),
729 }
730 }
731}
732
733#[derive(Debug, Clone, Error)]
734pub enum CapabilityProviderError {
735 #[error("bad path")]
736 BadPath,
737 #[error(transparent)]
738 ComponentInstanceError {
739 #[from]
740 err: ComponentInstanceError,
741 },
742 #[error(transparent)]
743 PkgDirError {
744 #[from]
745 err: PkgDirError,
746 },
747 #[error("event source: {0}")]
748 EventSourceError(#[from] EventSourceError),
749 #[error(transparent)]
750 ComponentProviderError {
751 #[from]
752 err: ComponentProviderError,
753 },
754 #[error("component_manager namespace: {err}")]
755 CmNamespaceError {
756 #[from]
757 err: ClonableError,
758 },
759 #[error("router: {err}")]
760 RouterError {
761 #[from]
762 err: RouterError,
763 },
764 #[error(transparent)]
765 RoutingError(#[from] RoutingError),
766 #[error("opening vfs failed: {0}")]
767 VfsOpenError(#[source] zx::Status),
768}
769
770impl CapabilityProviderError {
771 pub fn as_zx_status(&self) -> zx::Status {
772 match self {
773 Self::BadPath => zx::Status::INVALID_ARGS,
774 Self::ComponentInstanceError { err } => err.as_zx_status(),
775 Self::CmNamespaceError { .. } => zx::Status::INTERNAL,
776 Self::PkgDirError { err } => err.as_zx_status(),
777 Self::EventSourceError(err) => err.as_zx_status(),
778 Self::ComponentProviderError { err } => err.as_zx_status(),
779 Self::RouterError { err } => err.as_zx_status(),
780 Self::RoutingError(err) => err.as_zx_status(),
781 Self::VfsOpenError(err) => *err,
782 }
783 }
784}
785
786#[derive(Debug, Clone, Error)]
787pub enum OpenError {
788 #[error("failed to get default capability provider: {err}")]
789 GetDefaultProviderError {
790 #[source]
792 err: Box<ModelError>,
793 },
794 #[error("no capability provider found")]
795 CapabilityProviderNotFound,
796 #[error("capability provider: {err}")]
797 CapabilityProviderError {
798 #[from]
799 err: CapabilityProviderError,
800 },
801 #[error("opening storage capability: {err}")]
802 OpenStorageError {
803 #[source]
805 err: Box<ModelError>,
806 },
807 #[error("timed out opening capability")]
808 Timeout,
809 #[error("invalid path found")]
810 BadPath,
811 #[error("capability does not support opening: {0}")]
812 DoesNotSupportOpen(ConversionError),
813 #[error("failed to create directory watcher: {err}")]
814 WatcherCreateError {
815 #[from]
816 err: WatcherCreateError,
817 },
818}
819
820impl Explain for OpenError {
821 fn as_zx_status(&self) -> zx::Status {
822 match self {
823 Self::GetDefaultProviderError { err } => err.as_zx_status(),
824 Self::OpenStorageError { err } => err.as_zx_status(),
825 Self::CapabilityProviderError { err } => err.as_zx_status(),
826 Self::CapabilityProviderNotFound => zx::Status::NOT_FOUND,
827 Self::Timeout => zx::Status::TIMED_OUT,
828 Self::BadPath => zx::Status::BAD_PATH,
829 Self::DoesNotSupportOpen(_) => zx::Status::NOT_SUPPORTED,
830 Self::WatcherCreateError { err: WatcherCreateError::SendWatchRequest(_err) } => {
831 zx::Status::PEER_CLOSED
832 }
833 Self::WatcherCreateError { err: WatcherCreateError::WatchError(status) } => *status,
834 Self::WatcherCreateError { err: WatcherCreateError::ChannelConversion(status) } => {
835 *status
836 }
837 }
838 }
839}
840
841impl From<OpenError> for RouterError {
842 fn from(value: OpenError) -> Self {
843 Self::NotFound(Arc::new(value))
844 }
845}
846
847#[derive(Debug, Clone, Error)]
848pub enum StartActionError {
849 #[error("`{moniker}` was shut down")]
850 InstanceShutDown { moniker: Moniker },
851 #[error("`{moniker}` was destroyed")]
852 InstanceDestroyed { moniker: Moniker },
853 #[error("`{moniker}` couldn't resolve during start: {err}")]
854 ResolveActionError {
855 moniker: Moniker,
856 #[source]
857 err: Box<ActionError>,
858 },
859 #[error("runner for `{moniker}` `{runner}` couldn't resolve: {err}")]
860 ResolveRunnerError {
861 moniker: Moniker,
862 runner: Name,
863 #[source]
864 err: Box<RouterError>,
865 },
866 #[error(
867 "`{moniker}` uses `\"on_terminate\": \"reboot\"` but is disallowed by policy:\n\t{err}"
868 )]
869 RebootOnTerminateForbidden {
870 moniker: Moniker,
871 #[source]
872 err: PolicyError,
873 },
874 #[error("creating program input dictionary for `{moniker}`")]
875 InputDictionaryError { moniker: Moniker },
876 #[error("creating namespace: {0}")]
877 CreateNamespaceError(#[from] CreateNamespaceError),
878 #[error("starting program for `{moniker}`: {err}")]
879 StartProgramError {
880 moniker: Moniker,
881 #[source]
882 err: StartError,
883 },
884 #[error("structured configuration for `{moniker}`: {err}")]
885 StructuredConfigError {
886 moniker: Moniker,
887 #[source]
888 err: StructuredConfigError,
889 },
890 #[error("starting eager child of `{moniker}`: {err}")]
891 EagerStartError {
892 moniker: Moniker,
893 #[source]
894 err: Box<ActionError>,
895 },
896 #[error("`{moniker}` was interrupted")]
897 Aborted { moniker: Moniker },
898}
899
900impl StartActionError {
901 fn as_zx_status(&self) -> zx::Status {
902 match self {
903 StartActionError::InstanceDestroyed { .. } | Self::InstanceShutDown { .. } => {
904 zx::Status::NOT_FOUND
905 }
906 StartActionError::StartProgramError { .. }
907 | StartActionError::StructuredConfigError { .. }
908 | StartActionError::EagerStartError { .. } => zx::Status::INTERNAL,
909 StartActionError::RebootOnTerminateForbidden { err, .. } => err.as_zx_status(),
910 StartActionError::ResolveRunnerError { err, .. } => err.as_zx_status(),
911 StartActionError::CreateNamespaceError(err) => err.as_zx_status(),
912 StartActionError::InputDictionaryError { .. } => zx::Status::NOT_FOUND,
913 StartActionError::ResolveActionError { err, .. } => err.as_zx_status(),
914 StartActionError::Aborted { .. } => zx::Status::NOT_FOUND,
915 }
916 }
917}
918
919impl Into<fsys::StartError> for StartActionError {
921 fn into(self) -> fsys::StartError {
922 match self {
923 StartActionError::ResolveActionError { err, .. } => (*err).into(),
924 StartActionError::InstanceDestroyed { .. } => fsys::StartError::InstanceNotFound,
925 StartActionError::InstanceShutDown { .. } => fsys::StartError::InstanceNotFound,
926 _ => fsys::StartError::Internal,
927 }
928 }
929}
930
931impl Into<fcomponent::Error> for StartActionError {
933 fn into(self) -> fcomponent::Error {
934 match self {
935 StartActionError::ResolveActionError { .. } => fcomponent::Error::InstanceCannotResolve,
936 StartActionError::RebootOnTerminateForbidden { .. } => fcomponent::Error::AccessDenied,
937 StartActionError::InstanceShutDown { .. } => fcomponent::Error::InstanceDied,
938 StartActionError::InstanceDestroyed { .. } => fcomponent::Error::InstanceDied,
939 _ => fcomponent::Error::InstanceCannotStart,
940 }
941 }
942}
943
944#[derive(Debug, Clone, Error)]
945pub enum StopActionError {
946 #[error("stopping program: {0}")]
947 ProgramStopError(#[source] StopError),
948 #[error("failed to get top instance")]
949 GetTopInstanceFailed,
950 #[error("failed to get parent instance")]
951 GetParentFailed,
952 #[error("failed to destroy dynamic children: {err}")]
953 DestroyDynamicChildrenFailed { err: Box<ActionError> },
954 #[error("resolution during stop: {err}")]
955 ResolveActionError {
956 #[source]
957 err: Box<ActionError>,
958 },
959 #[error("started while shutdown was ongoing")]
960 ComponentStartedDuringShutdown,
961}
962
963impl Into<fsys::StopError> for StopActionError {
965 fn into(self) -> fsys::StopError {
966 fsys::StopError::Internal
967 }
968}
969
970impl Into<fcomponent::Error> for StopActionError {
971 fn into(self) -> fcomponent::Error {
972 fcomponent::Error::Internal
973 }
974}
975
976#[cfg(test)]
977impl PartialEq for StopActionError {
978 fn eq(&self, other: &Self) -> bool {
979 match (self, other) {
980 (StopActionError::ProgramStopError(_), StopActionError::ProgramStopError(_)) => true,
981 (StopActionError::GetTopInstanceFailed, StopActionError::GetTopInstanceFailed) => true,
982 (StopActionError::GetParentFailed, StopActionError::GetParentFailed) => true,
983 (
984 StopActionError::DestroyDynamicChildrenFailed { .. },
985 StopActionError::DestroyDynamicChildrenFailed { .. },
986 ) => true,
987 (
988 StopActionError::ResolveActionError { .. },
989 StopActionError::ResolveActionError { .. },
990 ) => true,
991 _ => false,
992 }
993 }
994}
995
996#[derive(Debug, Clone, Error)]
997pub enum ShutdownActionError {
998 #[error("child name invalid: {}", err)]
999 InvalidChildName {
1000 #[from]
1001 err: MonikerError,
1002 },
1003 #[error("cycles detected in graph")]
1004 CyclesDetected {},
1005}
1006
1007#[derive(Debug, Clone, Error)]
1008pub enum DestroyActionError {
1009 #[error("discover during destroy: {}", err)]
1010 DiscoverActionError {
1011 #[from]
1012 err: DiscoverActionError,
1013 },
1014 #[error("shutdown during destroy: {}", err)]
1015 ShutdownFailed {
1016 #[source]
1017 err: Box<ActionError>,
1018 },
1019 #[error("could not find `{moniker}`")]
1020 InstanceNotFound { moniker: Moniker },
1021 #[error("`{moniker}` is not resolved")]
1022 InstanceNotResolved { moniker: Moniker },
1023}
1024
1025impl Into<fcomponent::Error> for DestroyActionError {
1027 fn into(self) -> fcomponent::Error {
1028 match self {
1029 DestroyActionError::InstanceNotFound { .. } => fcomponent::Error::InstanceNotFound,
1030 _ => fcomponent::Error::Internal,
1031 }
1032 }
1033}
1034
1035impl Into<fsys::DestroyError> for DestroyActionError {
1037 fn into(self) -> fsys::DestroyError {
1038 match self {
1039 DestroyActionError::InstanceNotFound { .. } => fsys::DestroyError::InstanceNotFound,
1040 DestroyActionError::InstanceNotResolved { .. } => {
1041 fsys::DestroyError::InstanceNotResolved
1042 }
1043 _ => fsys::DestroyError::Internal,
1044 }
1045 }
1046}
1047
1048#[derive(Debug, Clone, Error)]
1049pub enum UnresolveActionError {
1050 #[error("shutdown during unresolve: {err}")]
1051 ShutdownFailed {
1052 #[from]
1053 err: StopActionError,
1054 },
1055 #[error("`{moniker}` cannot be unresolved while it is running")]
1056 InstanceRunning { moniker: Moniker },
1057 #[error("`{moniker}` was destroyed")]
1058 InstanceDestroyed { moniker: Moniker },
1059}
1060
1061impl Into<fsys::UnresolveError> for UnresolveActionError {
1063 fn into(self) -> fsys::UnresolveError {
1064 match self {
1065 UnresolveActionError::InstanceDestroyed { .. } => {
1066 fsys::UnresolveError::InstanceNotFound
1067 }
1068 _ => fsys::UnresolveError::Internal,
1069 }
1070 }
1071}
1072
1073#[derive(Debug, Clone, Error)]
1074pub enum CreateNamespaceError {
1075 #[error("failed to clone pkg dir for {moniker}: {err}")]
1076 ClonePkgDirFailed {
1077 moniker: Moniker,
1078 #[source]
1079 err: fuchsia_fs::node::CloneError,
1080 },
1081
1082 #[error("use decl without path cannot be installed into the namespace for {moniker}: {decl:?}")]
1083 UseDeclWithoutPath { moniker: Moniker, decl: UseDecl },
1084
1085 #[error("instance not in index: {0}")]
1086 InstanceNotInInstanceIdIndex(#[from] RoutingError),
1087
1088 #[error("building namespace for {moniker}: {err}")]
1089 BuildNamespaceError {
1090 moniker: Moniker,
1091 #[source]
1092 err: serve_processargs::BuildNamespaceError,
1093 },
1094
1095 #[error("failed to convert namespace into directory for {moniker}: {err}")]
1096 ConvertToDirectory {
1097 moniker: Moniker,
1098 #[source]
1099 err: ClonableError,
1100 },
1101
1102 #[error(transparent)]
1103 ComponentInstanceError(#[from] ComponentInstanceError),
1104}
1105
1106impl CreateNamespaceError {
1107 fn as_zx_status(&self) -> zx::Status {
1108 match self {
1109 Self::ClonePkgDirFailed { .. } => zx::Status::INTERNAL,
1110 Self::UseDeclWithoutPath { .. } => zx::Status::NOT_FOUND,
1111 Self::InstanceNotInInstanceIdIndex(err) => err.as_zx_status(),
1112 Self::BuildNamespaceError { .. } => zx::Status::NOT_FOUND,
1113 Self::ConvertToDirectory { .. } => zx::Status::INTERNAL,
1114 Self::ComponentInstanceError(err) => err.as_zx_status(),
1115 }
1116 }
1117}
1118
1119#[derive(Debug, Clone, Error)]
1120pub enum EventSourceError {
1121 #[error(transparent)]
1122 ComponentInstance(#[from] ComponentInstanceError),
1123 #[error(transparent)]
1124 Model(#[from] Box<ModelError>),
1126 #[error("event stream already consumed")]
1127 AlreadyConsumed,
1128}
1129
1130impl EventSourceError {
1131 fn as_zx_status(&self) -> zx::Status {
1132 match self {
1133 Self::ComponentInstance(err) => err.as_zx_status(),
1134 Self::Model(err) => err.as_zx_status(),
1135 Self::AlreadyConsumed => zx::Status::INTERNAL,
1136 }
1137 }
1138}
1139
1140#[derive(Debug, Error, Clone)]
1141pub enum EventsError {
1142 #[error("capability_requested event streams cannot be taken twice")]
1143 CapabilityRequestedStreamTaken,
1144
1145 #[error("model not available")]
1146 ModelNotAvailable,
1147
1148 #[error("instance shut down")]
1149 InstanceShutdown,
1150
1151 #[error("instance destroyed")]
1152 InstanceDestroyed,
1153
1154 #[error("registry not found")]
1155 RegistryNotFound,
1156
1157 #[error("event `{event_name}` appears more than once in a subscription request")]
1158 DuplicateEvent { event_name: Name },
1159
1160 #[error("events not available for subscription: `{names:?}`")]
1161 NotAvailable { names: Vec<Name> },
1162}
1163
1164impl EventsError {
1165 pub fn duplicate_event(event_name: Name) -> Self {
1166 Self::DuplicateEvent { event_name }
1167 }
1168
1169 pub fn not_available(names: Vec<Name>) -> Self {
1170 Self::NotAvailable { names }
1171 }
1172}
1173
1174#[derive(Debug, Error, Clone)]
1176pub enum StorageError {
1177 #[error("opening directory from `{dir_source_moniker:?}` at `{dir_source_path}`:\n\t{err}")]
1178 OpenRoot {
1179 dir_source_moniker: Option<Moniker>,
1180 dir_source_path: cm_types::Path,
1181 #[source]
1182 err: ClonableError,
1183 },
1184 #[error(
1185 "opening isolated storage from `{dir_source_moniker:?}`'s for `{moniker}` at `{dir_source_path}` (instance_id={instance_id:?}):\n\t{err}"
1186 )]
1187 Open {
1188 dir_source_moniker: Option<Moniker>,
1189 dir_source_path: cm_types::Path,
1190 moniker: Moniker,
1191 instance_id: Option<InstanceId>,
1192 #[source]
1193 err: ClonableError,
1194 },
1195 #[error(
1196 "opening isolated storage from `{dir_source_moniker:?}` at `{dir_source_path}` for {instance_id}:\n\t{err}"
1197 )]
1198 OpenById {
1199 dir_source_moniker: Option<Moniker>,
1200 dir_source_path: cm_types::Path,
1201 instance_id: InstanceId,
1202 #[source]
1203 err: ClonableError,
1204 },
1205 #[error(
1206 "removing isolated storage from {dir_source_moniker:?} at `{dir_source_path}` for `{moniker}` (instance_id={instance_id:?}):n\t{err} "
1207 )]
1208 Remove {
1209 dir_source_moniker: Option<Moniker>,
1210 dir_source_path: cm_types::Path,
1211 moniker: Moniker,
1212 instance_id: Option<InstanceId>,
1213 #[source]
1214 err: ClonableError,
1215 },
1216 #[error("storage path for `{moniker}` (instance_id={instance_id:?}) is invalid")]
1217 InvalidStoragePath { moniker: Moniker, instance_id: Option<InstanceId> },
1218}
1219
1220impl StorageError {
1221 pub fn open_root(
1222 dir_source_moniker: Option<Moniker>,
1223 dir_source_path: cm_types::Path,
1224 err: impl Into<Error>,
1225 ) -> Self {
1226 Self::OpenRoot { dir_source_moniker, dir_source_path, err: err.into().into() }
1227 }
1228
1229 pub fn open(
1230 dir_source_moniker: Option<Moniker>,
1231 dir_source_path: cm_types::Path,
1232 moniker: Moniker,
1233 instance_id: Option<InstanceId>,
1234 err: impl Into<Error>,
1235 ) -> Self {
1236 Self::Open {
1237 dir_source_moniker,
1238 dir_source_path,
1239 moniker,
1240 instance_id,
1241 err: err.into().into(),
1242 }
1243 }
1244
1245 pub fn open_by_id(
1246 dir_source_moniker: Option<Moniker>,
1247 dir_source_path: cm_types::Path,
1248 instance_id: InstanceId,
1249 err: impl Into<Error>,
1250 ) -> Self {
1251 Self::OpenById { dir_source_moniker, dir_source_path, instance_id, err: err.into().into() }
1252 }
1253
1254 pub fn remove(
1255 dir_source_moniker: Option<Moniker>,
1256 dir_source_path: cm_types::Path,
1257 moniker: Moniker,
1258 instance_id: Option<InstanceId>,
1259 err: impl Into<Error>,
1260 ) -> Self {
1261 Self::Remove {
1262 dir_source_moniker,
1263 dir_source_path,
1264 moniker,
1265 instance_id,
1266 err: err.into().into(),
1267 }
1268 }
1269
1270 pub fn invalid_storage_path(moniker: Moniker, instance_id: Option<InstanceId>) -> Self {
1271 Self::InvalidStoragePath { moniker, instance_id }
1272 }
1273}
1274
1275#[derive(Error, Debug, Clone)]
1276pub enum StartError {
1277 #[error("serving namespace: {0}")]
1278 ServeNamespace(BuildNamespaceError),
1279}
1280
1281#[derive(Error, Debug, Clone)]
1282pub enum StopError {
1283 #[error("internal: {0}")]
1285 Internal(fidl::Error),
1286}