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