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}
282
283impl Into<fcomponent::Error> for AddDynamicChildError {
285 fn into(self) -> fcomponent::Error {
286 match self {
287 AddDynamicChildError::CollectionNotFound { .. } => {
288 fcomponent::Error::CollectionNotFound
289 }
290 AddDynamicChildError::NumberedHandleNotInSingleRunCollection => {
291 fcomponent::Error::Unsupported
292 }
293 AddDynamicChildError::AddChildError {
294 err: AddChildError::InstanceAlreadyExists { .. },
295 } => fcomponent::Error::InstanceAlreadyExists,
296 AddDynamicChildError::DynamicOffersNotAllowed { .. } => {
297 fcomponent::Error::InvalidArguments
298 }
299 AddDynamicChildError::ActionError { err } => err.into(),
300 AddDynamicChildError::InvalidDictionary { .. } => fcomponent::Error::InvalidArguments,
301 AddDynamicChildError::StaticRouteConflict { .. } => fcomponent::Error::InvalidArguments,
302 AddDynamicChildError::NameTooLong { .. } => fcomponent::Error::InvalidArguments,
303 AddDynamicChildError::AddChildError {
306 err:
307 AddChildError::DynamicCapabilityError { err: DynamicCapabilityError::Cycle { .. } },
308 } => fcomponent::Error::DependencyCycle,
309 AddDynamicChildError::AddChildError {
310 err: AddChildError::DynamicCapabilityError { .. },
311 } => fcomponent::Error::InvalidArguments,
312 AddDynamicChildError::AddChildError { err: AddChildError::ChildNameInvalid { .. } } => {
313 fcomponent::Error::InvalidArguments
314 }
315 }
316 }
317}
318
319impl Into<fsys::CreateError> for AddDynamicChildError {
321 fn into(self) -> fsys::CreateError {
322 match self {
323 AddDynamicChildError::CollectionNotFound { .. } => {
324 fsys::CreateError::CollectionNotFound
325 }
326 AddDynamicChildError::AddChildError {
327 err: AddChildError::InstanceAlreadyExists { .. },
328 } => fsys::CreateError::InstanceAlreadyExists,
329
330 AddDynamicChildError::DynamicOffersNotAllowed { .. } => {
331 fsys::CreateError::DynamicOffersForbidden
332 }
333 AddDynamicChildError::ActionError { .. } => fsys::CreateError::Internal,
334 AddDynamicChildError::InvalidDictionary { .. } => fsys::CreateError::Internal,
335 AddDynamicChildError::StaticRouteConflict { .. } => fsys::CreateError::Internal,
336 AddDynamicChildError::NameTooLong { .. } => fsys::CreateError::BadChildDecl,
337 AddDynamicChildError::AddChildError {
338 err: AddChildError::DynamicCapabilityError { .. },
339 } => fsys::CreateError::BadDynamicOffer,
340 AddDynamicChildError::AddChildError { err: AddChildError::ChildNameInvalid { .. } } => {
341 fsys::CreateError::BadMoniker
342 }
343 AddDynamicChildError::NumberedHandleNotInSingleRunCollection => {
344 fsys::CreateError::NumberedHandlesForbidden
345 }
346 }
347 }
348}
349
350#[derive(Debug, Error, Clone)]
351pub enum AddChildError {
352 #[error("component instance `{child}` in realm `{moniker}` already exists")]
353 InstanceAlreadyExists { moniker: Moniker, child: ChildName },
354 #[error(transparent)]
355 DynamicCapabilityError {
356 #[from]
357 err: DynamicCapabilityError,
358 },
359 #[error("invalid child name: {err}")]
360 ChildNameInvalid {
361 #[from]
362 err: MonikerError,
363 },
364}
365
366#[derive(Debug, Error, Clone, PartialEq)]
367pub enum DynamicCapabilityError {
368 #[error("a dynamic capability was not valid:\n\t{err}")]
369 Invalid {
370 #[source]
371 err: cm_fidl_validator::error::ErrorList,
372 },
373 #[error("dynamic offers are not allowed for {typename}")]
374 UnsupportedType { typename: &'static str },
375 #[error("dynamic offer would create a cycle:\n\t{err}")]
376 Cycle {
377 #[source]
378 err: cm_fidl_validator::error::ErrorList,
379 },
380 #[error("source for dynamic offer not found:\n\t{:?}", offer)]
381 SourceNotFound { offer: cm_rust::OfferDecl },
382 #[error("unknown offer type in dynamic offers")]
383 UnknownOfferType,
384}
385
386#[derive(Debug, Clone, Error)]
387pub enum ActionError {
388 #[error("discover: {err}")]
389 DiscoverError {
390 #[from]
391 err: DiscoverActionError,
392 },
393
394 #[error("resolve: {err}")]
395 ResolveError {
396 #[from]
397 err: ResolveActionError,
398 },
399
400 #[error("unresolve: {err}")]
401 UnresolveError {
402 #[from]
403 err: UnresolveActionError,
404 },
405
406 #[error("start: {err}")]
407 StartError {
408 #[from]
409 err: StartActionError,
410 },
411
412 #[error("stop: {err}")]
413 StopError {
414 #[from]
415 err: StopActionError,
416 },
417
418 #[error("destroy: {err}")]
419 DestroyError {
420 #[from]
421 err: DestroyActionError,
422 },
423
424 #[error("shutdown: {err}")]
425 ShutdownError {
426 #[from]
427 err: ShutdownActionError,
428 },
429}
430
431impl Explain for ActionError {
432 fn as_zx_status(&self) -> zx::Status {
433 match self {
434 ActionError::DiscoverError { .. } => zx::Status::INTERNAL,
435 ActionError::ResolveError { err } => err.as_zx_status(),
436 ActionError::UnresolveError { .. } => zx::Status::INTERNAL,
437 ActionError::StartError { err } => err.as_zx_status(),
438 ActionError::StopError { .. } => zx::Status::INTERNAL,
439 ActionError::DestroyError { .. } => zx::Status::INTERNAL,
440 ActionError::ShutdownError { .. } => zx::Status::INTERNAL,
441 }
442 }
443}
444
445impl From<ActionError> for fcomponent::Error {
446 fn from(err: ActionError) -> Self {
447 match err {
448 ActionError::DiscoverError { .. } => fcomponent::Error::Internal,
449 ActionError::ResolveError { .. } => fcomponent::Error::Internal,
450 ActionError::UnresolveError { .. } => fcomponent::Error::Internal,
451 ActionError::StartError { err } => err.into(),
452 ActionError::StopError { err } => err.into(),
453 ActionError::DestroyError { err } => err.into(),
454 ActionError::ShutdownError { .. } => fcomponent::Error::Internal,
455 }
456 }
457}
458
459impl From<ActionError> for fsys::ResolveError {
460 fn from(err: ActionError) -> Self {
461 match err {
462 ActionError::ResolveError { err } => err.into(),
463 _ => fsys::ResolveError::Internal,
464 }
465 }
466}
467
468impl From<ActionError> for fsys::UnresolveError {
469 fn from(err: ActionError) -> Self {
470 match err {
471 ActionError::UnresolveError { err } => err.into(),
472 _ => fsys::UnresolveError::Internal,
473 }
474 }
475}
476
477impl From<ActionError> for fsys::StartError {
478 fn from(err: ActionError) -> Self {
479 match err {
480 ActionError::StartError { err } => err.into(),
481 _ => fsys::StartError::Internal,
482 }
483 }
484}
485
486impl From<ActionError> for fsys::StopError {
487 fn from(err: ActionError) -> Self {
488 match err {
489 ActionError::StopError { err } => err.into(),
490 _ => fsys::StopError::Internal,
491 }
492 }
493}
494
495impl From<ActionError> for fsys::DestroyError {
496 fn from(err: ActionError) -> Self {
497 match err {
498 ActionError::DestroyError { err } => err.into(),
499 _ => fsys::DestroyError::Internal,
500 }
501 }
502}
503
504#[derive(Debug, Clone, Error)]
505pub enum DiscoverActionError {
506 #[error("`{moniker}` was destroyed")]
507 InstanceDestroyed { moniker: Moniker },
508}
509
510#[derive(Debug, Clone, Error)]
511pub enum ResolveActionError {
512 #[error("discover during resolve: {err}")]
513 DiscoverActionError {
514 #[from]
515 err: DiscoverActionError,
516 },
517 #[error("`{moniker}` was shut down")]
518 InstanceShutDown { moniker: Moniker },
519 #[error("`{moniker}` was destroyed")]
520 InstanceDestroyed { moniker: Moniker },
521 #[error("could not parse component address for `{url}` at `{moniker}`:\n\t{err}")]
522 ComponentAddressParseError {
523 url: Url,
524 moniker: Moniker,
525 #[source]
526 err: ResolverError,
527 },
528 #[error("resolve failed for `{url}`:\n\t{err}")]
529 ResolverError {
530 url: Url,
531 #[source]
532 err: ResolverError,
533 },
534 #[error("expose dir for `{moniker}`:\n\t{err}")]
535 ExposeDirError {
537 moniker: Moniker,
538
539 #[source]
540 err: VfsError,
541 },
542 #[error("adding static child `{child_name}`:\n\t{err}")]
543 AddStaticChildError {
544 child_name: String,
545 #[source]
546 err: AddChildError,
547 },
548 #[error("structured config: {err}")]
549 StructuredConfigError {
550 #[from]
551 err: StructuredConfigError,
552 },
553 #[error("creating package dir proxy: {err}")]
554 PackageDirProxyCreateError {
555 #[source]
556 err: fidl::Error,
557 },
558 #[error("ABI compatibility check for `{url}`: {err}")]
559 AbiCompatibilityError {
560 url: Url,
561 #[source]
562 err: CompatibilityCheckError,
563 },
564 #[error(transparent)]
565 Policy(#[from] PolicyError),
566 #[error("`{moniker}` was interrupted")]
567 Aborted { moniker: Moniker },
568}
569
570impl ResolveActionError {
571 fn as_zx_status(&self) -> zx::Status {
572 match self {
573 ResolveActionError::DiscoverActionError { .. }
574 | ResolveActionError::InstanceShutDown { .. }
575 | ResolveActionError::InstanceDestroyed { .. }
576 | ResolveActionError::ComponentAddressParseError { .. }
577 | ResolveActionError::AbiCompatibilityError { .. } => zx::Status::NOT_FOUND,
578 ResolveActionError::ExposeDirError { .. }
579 | ResolveActionError::AddStaticChildError { .. }
580 | ResolveActionError::StructuredConfigError { .. }
581 | ResolveActionError::Aborted { .. }
582 | ResolveActionError::PackageDirProxyCreateError { .. } => zx::Status::INTERNAL,
583 ResolveActionError::ResolverError { err, .. } => err.as_zx_status(),
584 ResolveActionError::Policy(err) => err.as_zx_status(),
585 }
586 }
587}
588
589impl Into<fsys::ResolveError> for ResolveActionError {
591 fn into(self) -> fsys::ResolveError {
592 match self {
593 ResolveActionError::ResolverError {
594 err: ResolverError::PackageNotFound(_), ..
595 } => fsys::ResolveError::PackageNotFound,
596 ResolveActionError::ResolverError {
597 err: ResolverError::ManifestNotFound(_), ..
598 } => fsys::ResolveError::ManifestNotFound,
599 ResolveActionError::InstanceShutDown { .. }
600 | ResolveActionError::InstanceDestroyed { .. } => fsys::ResolveError::InstanceNotFound,
601 ResolveActionError::ExposeDirError { .. }
602 | ResolveActionError::ResolverError { .. }
603 | ResolveActionError::StructuredConfigError { .. }
604 | ResolveActionError::ComponentAddressParseError { .. }
605 | ResolveActionError::AddStaticChildError { .. }
606 | ResolveActionError::DiscoverActionError { .. }
607 | ResolveActionError::AbiCompatibilityError { .. }
608 | ResolveActionError::Aborted { .. }
609 | ResolveActionError::PackageDirProxyCreateError { .. } => fsys::ResolveError::Internal,
610 ResolveActionError::Policy(_) => fsys::ResolveError::PolicyError,
611 }
612 }
613}
614
615impl Into<fsys::StartError> for ResolveActionError {
618 fn into(self) -> fsys::StartError {
619 match self {
620 ResolveActionError::ResolverError {
621 err: ResolverError::PackageNotFound(_), ..
622 } => fsys::StartError::PackageNotFound,
623 ResolveActionError::ResolverError {
624 err: ResolverError::ManifestNotFound(_), ..
625 } => fsys::StartError::ManifestNotFound,
626 ResolveActionError::InstanceShutDown { .. }
627 | ResolveActionError::InstanceDestroyed { .. } => fsys::StartError::InstanceNotFound,
628 ResolveActionError::ExposeDirError { .. }
629 | ResolveActionError::ResolverError { .. }
630 | ResolveActionError::StructuredConfigError { .. }
631 | ResolveActionError::ComponentAddressParseError { .. }
632 | ResolveActionError::AddStaticChildError { .. }
633 | ResolveActionError::DiscoverActionError { .. }
634 | ResolveActionError::AbiCompatibilityError { .. }
635 | ResolveActionError::Aborted { .. }
636 | ResolveActionError::PackageDirProxyCreateError { .. } => fsys::StartError::Internal,
637 ResolveActionError::Policy(_) => fsys::StartError::PolicyError,
638 }
639 }
640}
641
642#[derive(Debug, Clone, Error)]
643pub enum PkgDirError {
644 #[error("no pkg dir found for component")]
645 NoPkgDir,
646 #[error("opening pkg dir failed: {err}")]
647 OpenFailed {
648 #[from]
649 err: zx::Status,
650 },
651}
652
653impl PkgDirError {
654 fn as_zx_status(&self) -> zx::Status {
655 match self {
656 Self::NoPkgDir => zx::Status::NOT_FOUND,
657 Self::OpenFailed { err } => *err,
658 }
659 }
660}
661
662#[derive(Debug, Clone, Error)]
663pub enum ComponentProviderError {
664 #[error("starting source instance:\n\t{err}")]
665 SourceStartError {
666 #[from]
667 err: ActionError,
668 },
669 #[error("opening source instance's outgoing dir:\n\t{err}")]
670 OpenOutgoingDirError {
671 #[from]
672 err: OpenOutgoingDirError,
673 },
674}
675
676impl ComponentProviderError {
677 pub fn as_zx_status(&self) -> zx::Status {
678 match self {
679 Self::SourceStartError { err } => err.as_zx_status(),
680 Self::OpenOutgoingDirError { err } => err.as_zx_status(),
681 }
682 }
683}
684
685#[derive(Debug, Clone, Error)]
686pub enum CapabilityProviderError {
687 #[error("bad path")]
688 BadPath,
689 #[error(transparent)]
690 ComponentInstanceError {
691 #[from]
692 err: ComponentInstanceError,
693 },
694 #[error(transparent)]
695 PkgDirError {
696 #[from]
697 err: PkgDirError,
698 },
699 #[error("event source: {0}")]
700 EventSourceError(#[from] EventSourceError),
701 #[error(transparent)]
702 ComponentProviderError {
703 #[from]
704 err: ComponentProviderError,
705 },
706 #[error("component_manager namespace: {err}")]
707 CmNamespaceError {
708 #[from]
709 err: ClonableError,
710 },
711 #[error("router: {err}")]
712 RouterError {
713 #[from]
714 err: RouterError,
715 },
716 #[error(transparent)]
717 RoutingError(#[from] RoutingError),
718 #[error("opening vfs failed: {0}")]
719 VfsOpenError(#[source] zx::Status),
720}
721
722impl CapabilityProviderError {
723 pub fn as_zx_status(&self) -> zx::Status {
724 match self {
725 Self::BadPath => zx::Status::INVALID_ARGS,
726 Self::ComponentInstanceError { err } => err.as_zx_status(),
727 Self::CmNamespaceError { .. } => zx::Status::INTERNAL,
728 Self::PkgDirError { err } => err.as_zx_status(),
729 Self::EventSourceError(err) => err.as_zx_status(),
730 Self::ComponentProviderError { err } => err.as_zx_status(),
731 Self::RouterError { err } => err.as_zx_status(),
732 Self::RoutingError(err) => err.as_zx_status(),
733 Self::VfsOpenError(err) => *err,
734 }
735 }
736}
737
738#[derive(Debug, Clone, Error)]
739pub enum OpenError {
740 #[error("failed to get default capability provider: {err}")]
741 GetDefaultProviderError {
742 #[source]
744 err: Box<ModelError>,
745 },
746 #[error("no capability provider found")]
747 CapabilityProviderNotFound,
748 #[error("capability provider: {err}")]
749 CapabilityProviderError {
750 #[from]
751 err: CapabilityProviderError,
752 },
753 #[error("opening storage capability: {err}")]
754 OpenStorageError {
755 #[source]
757 err: Box<ModelError>,
758 },
759 #[error("timed out opening capability")]
760 Timeout,
761 #[error("invalid path found")]
762 BadPath,
763 #[error("capability does not support opening: {0}")]
764 DoesNotSupportOpen(ConversionError),
765 #[error("failed to create directory watcher: {err}")]
766 WatcherCreateError {
767 #[from]
768 err: WatcherCreateError,
769 },
770}
771
772impl Explain for OpenError {
773 fn as_zx_status(&self) -> zx::Status {
774 match self {
775 Self::GetDefaultProviderError { err } => err.as_zx_status(),
776 Self::OpenStorageError { err } => err.as_zx_status(),
777 Self::CapabilityProviderError { err } => err.as_zx_status(),
778 Self::CapabilityProviderNotFound => zx::Status::NOT_FOUND,
779 Self::Timeout => zx::Status::TIMED_OUT,
780 Self::BadPath => zx::Status::BAD_PATH,
781 Self::DoesNotSupportOpen(_) => zx::Status::NOT_SUPPORTED,
782 Self::WatcherCreateError { err: WatcherCreateError::SendWatchRequest(_err) } => {
783 zx::Status::PEER_CLOSED
784 }
785 Self::WatcherCreateError { err: WatcherCreateError::WatchError(status) } => *status,
786 Self::WatcherCreateError { err: WatcherCreateError::ChannelConversion(status) } => {
787 *status
788 }
789 }
790 }
791}
792
793impl From<OpenError> for RouterError {
794 fn from(value: OpenError) -> Self {
795 Self::NotFound(Arc::new(value))
796 }
797}
798
799#[derive(Debug, Clone, Error)]
800pub enum StartActionError {
801 #[error("`{moniker}` was shut down")]
802 InstanceShutDown { moniker: Moniker },
803 #[error("`{moniker}` was destroyed")]
804 InstanceDestroyed { moniker: Moniker },
805 #[error("`{moniker}` couldn't resolve during start: {err}")]
806 ResolveActionError {
807 moniker: Moniker,
808 #[source]
809 err: Box<ActionError>,
810 },
811 #[error("runner for `{moniker}` `{runner}` couldn't resolve: {err}")]
812 ResolveRunnerError {
813 moniker: Moniker,
814 runner: Name,
815 #[source]
816 err: Box<RouterError>,
817 },
818 #[error(
819 "`{moniker}` uses `\"on_terminate\": \"reboot\"` but is disallowed by policy:\n\t{err}"
820 )]
821 RebootOnTerminateForbidden {
822 moniker: Moniker,
823 #[source]
824 err: PolicyError,
825 },
826 #[error("creating program input dictionary for `{moniker}`")]
827 InputDictionaryError { moniker: Moniker },
828 #[error("creating namespace: {0}")]
829 CreateNamespaceError(#[from] CreateNamespaceError),
830 #[error("starting program for `{moniker}`: {err}")]
831 StartProgramError {
832 moniker: Moniker,
833 #[source]
834 err: StartError,
835 },
836 #[error("structured configuration for `{moniker}`: {err}")]
837 StructuredConfigError {
838 moniker: Moniker,
839 #[source]
840 err: StructuredConfigError,
841 },
842 #[error("starting eager child of `{moniker}`: {err}")]
843 EagerStartError {
844 moniker: Moniker,
845 #[source]
846 err: Box<ActionError>,
847 },
848 #[error("`{moniker}` was interrupted")]
849 Aborted { moniker: Moniker },
850}
851
852impl StartActionError {
853 fn as_zx_status(&self) -> zx::Status {
854 match self {
855 StartActionError::InstanceDestroyed { .. } | Self::InstanceShutDown { .. } => {
856 zx::Status::NOT_FOUND
857 }
858 StartActionError::StartProgramError { .. }
859 | StartActionError::StructuredConfigError { .. }
860 | StartActionError::EagerStartError { .. } => zx::Status::INTERNAL,
861 StartActionError::RebootOnTerminateForbidden { err, .. } => err.as_zx_status(),
862 StartActionError::ResolveRunnerError { err, .. } => err.as_zx_status(),
863 StartActionError::CreateNamespaceError(err) => err.as_zx_status(),
864 StartActionError::InputDictionaryError { .. } => zx::Status::NOT_FOUND,
865 StartActionError::ResolveActionError { err, .. } => err.as_zx_status(),
866 StartActionError::Aborted { .. } => zx::Status::NOT_FOUND,
867 }
868 }
869}
870
871impl Into<fsys::StartError> for StartActionError {
873 fn into(self) -> fsys::StartError {
874 match self {
875 StartActionError::ResolveActionError { err, .. } => (*err).into(),
876 StartActionError::InstanceDestroyed { .. } => fsys::StartError::InstanceNotFound,
877 StartActionError::InstanceShutDown { .. } => fsys::StartError::InstanceNotFound,
878 _ => fsys::StartError::Internal,
879 }
880 }
881}
882
883impl Into<fcomponent::Error> for StartActionError {
885 fn into(self) -> fcomponent::Error {
886 match self {
887 StartActionError::ResolveActionError { .. } => fcomponent::Error::InstanceCannotResolve,
888 StartActionError::RebootOnTerminateForbidden { .. } => fcomponent::Error::AccessDenied,
889 StartActionError::InstanceShutDown { .. } => fcomponent::Error::InstanceDied,
890 StartActionError::InstanceDestroyed { .. } => fcomponent::Error::InstanceDied,
891 _ => fcomponent::Error::InstanceCannotStart,
892 }
893 }
894}
895
896#[derive(Debug, Clone, Error)]
897pub enum StopActionError {
898 #[error("stopping program: {0}")]
899 ProgramStopError(#[source] StopError),
900 #[error("failed to get top instance")]
901 GetTopInstanceFailed,
902 #[error("failed to get parent instance")]
903 GetParentFailed,
904 #[error("failed to destroy dynamic children: {err}")]
905 DestroyDynamicChildrenFailed { err: Box<ActionError> },
906 #[error("resolution during stop: {err}")]
907 ResolveActionError {
908 #[source]
909 err: Box<ActionError>,
910 },
911 #[error("started while shutdown was ongoing")]
912 ComponentStartedDuringShutdown,
913}
914
915impl Into<fsys::StopError> for StopActionError {
917 fn into(self) -> fsys::StopError {
918 fsys::StopError::Internal
919 }
920}
921
922impl Into<fcomponent::Error> for StopActionError {
923 fn into(self) -> fcomponent::Error {
924 fcomponent::Error::Internal
925 }
926}
927
928#[cfg(test)]
929impl PartialEq for StopActionError {
930 fn eq(&self, other: &Self) -> bool {
931 match (self, other) {
932 (StopActionError::ProgramStopError(_), StopActionError::ProgramStopError(_)) => true,
933 (StopActionError::GetTopInstanceFailed, StopActionError::GetTopInstanceFailed) => true,
934 (StopActionError::GetParentFailed, StopActionError::GetParentFailed) => true,
935 (
936 StopActionError::DestroyDynamicChildrenFailed { .. },
937 StopActionError::DestroyDynamicChildrenFailed { .. },
938 ) => true,
939 (
940 StopActionError::ResolveActionError { .. },
941 StopActionError::ResolveActionError { .. },
942 ) => true,
943 _ => false,
944 }
945 }
946}
947
948#[derive(Debug, Clone, Error)]
949pub enum ShutdownActionError {
950 #[error("child name invalid: {}", err)]
951 InvalidChildName {
952 #[from]
953 err: MonikerError,
954 },
955 #[error("cycles detected in graph")]
956 CyclesDetected {},
957}
958
959#[derive(Debug, Clone, Error)]
960pub enum DestroyActionError {
961 #[error("discover during destroy: {}", err)]
962 DiscoverActionError {
963 #[from]
964 err: DiscoverActionError,
965 },
966 #[error("shutdown during destroy: {}", err)]
967 ShutdownFailed {
968 #[source]
969 err: Box<ActionError>,
970 },
971 #[error("could not find `{moniker}`")]
972 InstanceNotFound { moniker: Moniker },
973 #[error("`{moniker}` is not resolved")]
974 InstanceNotResolved { moniker: Moniker },
975}
976
977impl Into<fcomponent::Error> for DestroyActionError {
979 fn into(self) -> fcomponent::Error {
980 match self {
981 DestroyActionError::InstanceNotFound { .. } => fcomponent::Error::InstanceNotFound,
982 _ => fcomponent::Error::Internal,
983 }
984 }
985}
986
987impl Into<fsys::DestroyError> for DestroyActionError {
989 fn into(self) -> fsys::DestroyError {
990 match self {
991 DestroyActionError::InstanceNotFound { .. } => fsys::DestroyError::InstanceNotFound,
992 DestroyActionError::InstanceNotResolved { .. } => {
993 fsys::DestroyError::InstanceNotResolved
994 }
995 _ => fsys::DestroyError::Internal,
996 }
997 }
998}
999
1000#[derive(Debug, Clone, Error)]
1001pub enum UnresolveActionError {
1002 #[error("shutdown during unresolve: {err}")]
1003 ShutdownFailed {
1004 #[from]
1005 err: StopActionError,
1006 },
1007 #[error("`{moniker}` cannot be unresolved while it is running")]
1008 InstanceRunning { moniker: Moniker },
1009 #[error("`{moniker}` was destroyed")]
1010 InstanceDestroyed { moniker: Moniker },
1011}
1012
1013impl Into<fsys::UnresolveError> for UnresolveActionError {
1015 fn into(self) -> fsys::UnresolveError {
1016 match self {
1017 UnresolveActionError::InstanceDestroyed { .. } => {
1018 fsys::UnresolveError::InstanceNotFound
1019 }
1020 _ => fsys::UnresolveError::Internal,
1021 }
1022 }
1023}
1024
1025#[derive(Debug, Clone, Error)]
1026pub enum CreateNamespaceError {
1027 #[error("failed to clone pkg dir for {moniker}: {err}")]
1028 ClonePkgDirFailed {
1029 moniker: Moniker,
1030 #[source]
1031 err: fuchsia_fs::node::CloneError,
1032 },
1033
1034 #[error("use decl without path cannot be installed into the namespace for {moniker}: {decl:?}")]
1035 UseDeclWithoutPath { moniker: Moniker, decl: UseDecl },
1036
1037 #[error("instance not in index: {0}")]
1038 InstanceNotInInstanceIdIndex(#[from] RoutingError),
1039
1040 #[error("building namespace for {moniker}: {err}")]
1041 BuildNamespaceError {
1042 moniker: Moniker,
1043 #[source]
1044 err: serve_processargs::BuildNamespaceError,
1045 },
1046
1047 #[error("failed to convert namespace into directory for {moniker}: {err}")]
1048 ConvertToDirectory {
1049 moniker: Moniker,
1050 #[source]
1051 err: ClonableError,
1052 },
1053
1054 #[error(transparent)]
1055 ComponentInstanceError(#[from] ComponentInstanceError),
1056}
1057
1058impl CreateNamespaceError {
1059 fn as_zx_status(&self) -> zx::Status {
1060 match self {
1061 Self::ClonePkgDirFailed { .. } => zx::Status::INTERNAL,
1062 Self::UseDeclWithoutPath { .. } => zx::Status::NOT_FOUND,
1063 Self::InstanceNotInInstanceIdIndex(err) => err.as_zx_status(),
1064 Self::BuildNamespaceError { .. } => zx::Status::NOT_FOUND,
1065 Self::ConvertToDirectory { .. } => zx::Status::INTERNAL,
1066 Self::ComponentInstanceError(err) => err.as_zx_status(),
1067 }
1068 }
1069}
1070
1071#[derive(Debug, Clone, Error)]
1072pub enum EventSourceError {
1073 #[error(transparent)]
1074 ComponentInstance(#[from] ComponentInstanceError),
1075 #[error(transparent)]
1076 Model(#[from] Box<ModelError>),
1078 #[error("event stream already consumed")]
1079 AlreadyConsumed,
1080}
1081
1082impl EventSourceError {
1083 fn as_zx_status(&self) -> zx::Status {
1084 match self {
1085 Self::ComponentInstance(err) => err.as_zx_status(),
1086 Self::Model(err) => err.as_zx_status(),
1087 Self::AlreadyConsumed => zx::Status::INTERNAL,
1088 }
1089 }
1090}
1091
1092#[derive(Debug, Error, Clone)]
1093pub enum EventsError {
1094 #[error("capability_requested event streams cannot be taken twice")]
1095 CapabilityRequestedStreamTaken,
1096
1097 #[error("model not available")]
1098 ModelNotAvailable,
1099
1100 #[error("instance shut down")]
1101 InstanceShutdown,
1102
1103 #[error("instance destroyed")]
1104 InstanceDestroyed,
1105
1106 #[error("registry not found")]
1107 RegistryNotFound,
1108
1109 #[error("event `{event_name}` appears more than once in a subscription request")]
1110 DuplicateEvent { event_name: Name },
1111
1112 #[error("events not available for subscription: `{names:?}`")]
1113 NotAvailable { names: Vec<Name> },
1114}
1115
1116impl EventsError {
1117 pub fn duplicate_event(event_name: Name) -> Self {
1118 Self::DuplicateEvent { event_name }
1119 }
1120
1121 pub fn not_available(names: Vec<Name>) -> Self {
1122 Self::NotAvailable { names }
1123 }
1124}
1125
1126#[derive(Debug, Error, Clone)]
1128pub enum StorageError {
1129 #[error("opening directory from `{dir_source_moniker:?}` at `{dir_source_path}`:\n\t{err}")]
1130 OpenRoot {
1131 dir_source_moniker: Option<Moniker>,
1132 dir_source_path: cm_types::Path,
1133 #[source]
1134 err: ClonableError,
1135 },
1136 #[error(
1137 "opening isolated storage from `{dir_source_moniker:?}`'s for `{moniker}` at `{dir_source_path}` (instance_id={instance_id:?}):\n\t{err}"
1138 )]
1139 Open {
1140 dir_source_moniker: Option<Moniker>,
1141 dir_source_path: cm_types::Path,
1142 moniker: Moniker,
1143 instance_id: Option<InstanceId>,
1144 #[source]
1145 err: ClonableError,
1146 },
1147 #[error(
1148 "opening isolated storage from `{dir_source_moniker:?}` at `{dir_source_path}` for {instance_id}:\n\t{err}"
1149 )]
1150 OpenById {
1151 dir_source_moniker: Option<Moniker>,
1152 dir_source_path: cm_types::Path,
1153 instance_id: InstanceId,
1154 #[source]
1155 err: ClonableError,
1156 },
1157 #[error(
1158 "removing isolated storage from {dir_source_moniker:?} at `{dir_source_path}` for `{moniker}` (instance_id={instance_id:?}):n\t{err} "
1159 )]
1160 Remove {
1161 dir_source_moniker: Option<Moniker>,
1162 dir_source_path: cm_types::Path,
1163 moniker: Moniker,
1164 instance_id: Option<InstanceId>,
1165 #[source]
1166 err: ClonableError,
1167 },
1168 #[error("storage path for `{moniker}` (instance_id={instance_id:?}) is invalid")]
1169 InvalidStoragePath { moniker: Moniker, instance_id: Option<InstanceId> },
1170}
1171
1172impl StorageError {
1173 pub fn open_root(
1174 dir_source_moniker: Option<Moniker>,
1175 dir_source_path: cm_types::Path,
1176 err: impl Into<Error>,
1177 ) -> Self {
1178 Self::OpenRoot { dir_source_moniker, dir_source_path, err: err.into().into() }
1179 }
1180
1181 pub fn open(
1182 dir_source_moniker: Option<Moniker>,
1183 dir_source_path: cm_types::Path,
1184 moniker: Moniker,
1185 instance_id: Option<InstanceId>,
1186 err: impl Into<Error>,
1187 ) -> Self {
1188 Self::Open {
1189 dir_source_moniker,
1190 dir_source_path,
1191 moniker,
1192 instance_id,
1193 err: err.into().into(),
1194 }
1195 }
1196
1197 pub fn open_by_id(
1198 dir_source_moniker: Option<Moniker>,
1199 dir_source_path: cm_types::Path,
1200 instance_id: InstanceId,
1201 err: impl Into<Error>,
1202 ) -> Self {
1203 Self::OpenById { dir_source_moniker, dir_source_path, instance_id, err: err.into().into() }
1204 }
1205
1206 pub fn remove(
1207 dir_source_moniker: Option<Moniker>,
1208 dir_source_path: cm_types::Path,
1209 moniker: Moniker,
1210 instance_id: Option<InstanceId>,
1211 err: impl Into<Error>,
1212 ) -> Self {
1213 Self::Remove {
1214 dir_source_moniker,
1215 dir_source_path,
1216 moniker,
1217 instance_id,
1218 err: err.into().into(),
1219 }
1220 }
1221
1222 pub fn invalid_storage_path(moniker: Moniker, instance_id: Option<InstanceId>) -> Self {
1223 Self::InvalidStoragePath { moniker, instance_id }
1224 }
1225}
1226
1227#[derive(Error, Debug, Clone)]
1228pub enum StartError {
1229 #[error("serving namespace: {0}")]
1230 ServeNamespace(BuildNamespaceError),
1231}
1232
1233#[derive(Error, Debug, Clone)]
1234pub enum StopError {
1235 #[error("internal: {0}")]
1237 Internal(fidl::Error),
1238}